ARMAsmParser.cpp revision 9ab0f25fc194b4315db1b87d38d4024054120bf6
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"
25c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/Support/SourceMgr.h"
263e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h"
27fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar#include "llvm/Support/raw_ostream.h"
2811e03e7c2d0c163e54b911ad1e665616dc0bcc8cJim Grosbach#include "llvm/ADT/BitVector.h"
2975ca4b94bd9dcd3952fdc237429342a2154ba142Benjamin Kramer#include "llvm/ADT/OwningPtr.h"
3094b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/ADT/STLExtras.h"
31c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/SmallVector.h"
320c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson#include "llvm/ADT/StringExtras.h"
33345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar#include "llvm/ADT/StringSwitch.h"
34c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/Twine.h"
35ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
36ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyusing namespace llvm;
37ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
383a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace {
39146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling
40146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand;
4116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
4294b9550a32d189704a8eae55505edf62662c0534Evan Chengclass ARMAsmParser : public MCTargetAsmParser {
43ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  MCSubtargetInfo &STI;
44ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmParser &Parser;
45ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
46ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmParser &getParser() const { return Parser; }
47ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
48ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
49ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }
50ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
51ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
521355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  int tryParseRegister();
531355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool tryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &);
540d87ec21d79c8622733b8367aa41067169602480Jim Grosbach  int tryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &);
551355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &);
567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool parseMemory(SmallVectorImpl<MCParsedAsmOperand*> &);
571355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic);
581355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parsePrefix(ARMMCExpr::VariantKind &RefKind);
591355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  const MCExpr *applyPrefixToExpr(const MCExpr *E,
609081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim                                  MCSymbolRefExpr::VariantKind Variant);
619081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
62a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool parseMemRegOffsetShift(ARM_AM::ShiftOpc &ShiftType,
647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                              unsigned &ShiftAmount);
651355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveWord(unsigned Size, SMLoc L);
661355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveThumb(SMLoc L);
671355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveThumbFunc(SMLoc L);
681355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveCode(SMLoc L);
691355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveSyntax(SMLoc L);
70515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
711355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  StringRef splitMnemonic(StringRef Mnemonic, unsigned &PredicationCode,
725f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach                          bool &CarrySetting, unsigned &ProcessorIMod);
731355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  void getMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
74fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes                             bool &CanAcceptPredicationCode);
7516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
76ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  bool isThumb() const {
77ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    // FIXME: Can tablegen auto-generate this?
78ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    return (STI.getFeatureBits() & ARM::ModeThumb) != 0;
79ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
80ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  bool isThumbOne() const {
81ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) == 0;
82ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
8347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  bool isThumbTwo() const {
8447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2);
8547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  }
86194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  bool hasV6Ops() const {
87194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return STI.getFeatureBits() & ARM::HasV6Ops;
88194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  }
8932869205052430f45d598fba25ab878d8b29da2dEvan Cheng  void SwitchMode() {
90ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb));
91ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    setAvailableFeatures(FB);
9232869205052430f45d598fba25ab878d8b29da2dEvan Cheng  }
93ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
94a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// @name Auto-generated Match Functions
95a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// {
963483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
970692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER
980692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "ARMGenAsmMatcher.inc"
99a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
100a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// }
101a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
10243904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseCoprocNumOperand(
103f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
10443904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseCoprocRegOperand(
105f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
10643904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseMemBarrierOptOperand(
1078bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
10843904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseProcIFlagsOperand(
1098bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
11043904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseMSRMaskOperand(
1118bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
112f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &O,
113f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach                                   StringRef Op, int Low, int High);
114f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHLSLImm(SmallVectorImpl<MCParsedAsmOperand*> &O) {
115f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return parsePKHImm(O, "lsl", 0, 31);
116f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
117f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHASRImm(SmallVectorImpl<MCParsedAsmOperand*> &O) {
118f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return parsePKHImm(O, "asr", 1, 32);
119f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
120c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  OperandMatchResultTy parseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*>&);
121580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  OperandMatchResultTy parseShifterImm(SmallVectorImpl<MCParsedAsmOperand*>&);
1227e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  OperandMatchResultTy parseRotImm(SmallVectorImpl<MCParsedAsmOperand*>&);
123293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  OperandMatchResultTy parseBitfield(SmallVectorImpl<MCParsedAsmOperand*>&);
1247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  OperandMatchResultTy parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*>&);
125251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  OperandMatchResultTy parseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*>&);
126ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
127ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Asm Match Converter Methods
1281355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
129ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1309ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  bool cvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
1319ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
132548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  bool cvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
133548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1341355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
135ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1367b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  bool cvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
1377b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
1397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
1407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
1417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
1427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
1437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
1447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
1457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
1462fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  bool cvtLdrdPre(MCInst &Inst, unsigned Opcode,
1472fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach                  const SmallVectorImpl<MCParsedAsmOperand*> &);
14814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  bool cvtStrdPre(MCInst &Inst, unsigned Opcode,
14914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach                  const SmallVectorImpl<MCParsedAsmOperand*> &);
150623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  bool cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
151623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
15288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  bool cvtThumbMultiply(MCInst &Inst, unsigned Opcode,
15388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach                        const SmallVectorImpl<MCParsedAsmOperand*> &);
154189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
155189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  bool validateInstruction(MCInst &Inst,
156189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                           const SmallVectorImpl<MCParsedAsmOperand*> &Ops);
157f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach  void processInstruction(MCInst &Inst,
158f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach                          const SmallVectorImpl<MCParsedAsmOperand*> &Ops);
159d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  bool shouldOmitCCOutOperand(StringRef Mnemonic,
160d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach                              SmallVectorImpl<MCParsedAsmOperand*> &Operands);
161189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
162ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbypublic:
16347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  enum ARMMatchResultTy {
164194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY,
165194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    Match_RequiresV6,
166194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    Match_RequiresThumb2
16747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  };
16847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach
169ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser)
17094b9550a32d189704a8eae55505edf62662c0534Evan Cheng    : MCTargetAsmParser(), STI(_STI), Parser(_Parser) {
171ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    MCAsmParserExtension::Initialize(_Parser);
17232869205052430f45d598fba25ab878d8b29da2dEvan Cheng
173ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    // Initialize the set of available features.
174ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
175ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
176ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
1771355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  // Implementation of the MCTargetAsmParser interface:
1781355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
1791355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool ParseInstruction(StringRef Name, SMLoc NameLoc,
180189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                        SmallVectorImpl<MCParsedAsmOperand*> &Operands);
1811355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool ParseDirective(AsmToken DirectiveID);
1821355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach
18347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  unsigned checkTargetMatchPredicate(MCInst &Inst);
18447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach
1851355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool MatchAndEmitInstruction(SMLoc IDLoc,
1861355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach                               SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1871355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach                               MCStreamer &Out);
188ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby};
18916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach} // end anonymous namespace
19016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
1913a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace {
1923a69756e392942bc522193f38d7f33958ed3b131Chris Lattner
193a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine
194a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction.
195146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand : public MCParsedAsmOperand {
196762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  enum KindTy {
1978462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    CondCode,
198d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    CCOut,
199fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    CoprocNum,
200fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    CoprocReg,
201cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    Immediate,
202706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    MemBarrierOpt,
2038462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Memory,
2047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    PostIndexRegister,
205584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    MSRMask,
206a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    ProcIFlags,
2078462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Register,
2088d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    RegisterList,
2090f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    DPRRegisterList,
2100f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    SPRRegisterList,
211e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    ShiftedRegister,
21292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    ShiftedImmediate,
213580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    ShifterImmediate,
2147e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    RotateImmediate,
215293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    BitfieldDescriptor,
2168462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Token
217a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  } Kind;
218a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
219762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc StartLoc, EndLoc;
22024d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling  SmallVector<unsigned, 8> Registers;
221a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
222a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  union {
223a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
2248462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      ARMCC::CondCodes Val;
2258462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    } CC;
2268462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
2278462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    struct {
228706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      ARM_MB::MemBOpt Val;
229706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    } MBOpt;
230706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
231706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    struct {
232fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      unsigned Val;
233fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    } Cop;
234fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
235fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    struct {
236a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      ARM_PROC::IFlags Val;
237a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    } IFlags;
238a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
239a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    struct {
240584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      unsigned Val;
241584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    } MMask;
242584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
243584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    struct {
244a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      const char *Data;
245a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned Length;
246a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Tok;
247a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
248a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
249a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned RegNum;
250a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Reg;
251a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2528155e5b753aca42973cf317727f3805faddcaf90Bill Wendling    struct {
253cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby      const MCExpr *Val;
254cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    } Imm;
25516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2566a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar    /// Combined record for all forms of ARM address expressions.
257a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
258a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned BaseRegNum;
2597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // Offset is in OffsetReg or OffsetImm. If both are zero, no offset
2607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // was specified.
2617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      const MCConstantExpr *OffsetImm;  // Offset immediate value
2627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      unsigned OffsetRegNum;    // Offset register num, when OffsetImm == NULL
2637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      ARM_AM::ShiftOpc ShiftType; // Shift type for OffsetReg
2640d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach      unsigned ShiftImm;      // shift for OffsetReg.
2657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      unsigned isNegative : 1;  // Negated OffsetReg? (~'U' bit)
266a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Mem;
2670082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
2680082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    struct {
2697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      unsigned RegNum;
270f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      bool isAdd;
271f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      ARM_AM::ShiftOpc ShiftTy;
272f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      unsigned ShiftImm;
2737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    } PostIdxReg;
2747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
2757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    struct {
276580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      bool isASR;
277e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned Imm;
278580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    } ShifterImm;
279e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    struct {
280e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      ARM_AM::ShiftOpc ShiftTy;
281e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned SrcReg;
282e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned ShiftReg;
283e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned ShiftImm;
284af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    } RegShiftedReg;
28592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    struct {
28692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      ARM_AM::ShiftOpc ShiftTy;
28792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      unsigned SrcReg;
28892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      unsigned ShiftImm;
289af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    } RegShiftedImm;
2907e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    struct {
2917e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach      unsigned Imm;
2927e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    } RotImm;
293293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    struct {
294293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      unsigned LSB;
295293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      unsigned Width;
296293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    } Bitfield;
297a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  };
29816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
299146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
300146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingpublic:
301762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() {
302762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Kind = o.Kind;
303762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    StartLoc = o.StartLoc;
304762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    EndLoc = o.EndLoc;
305762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    switch (Kind) {
3068462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    case CondCode:
3078462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      CC = o.CC;
3088462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      break;
309762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Token:
3108462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      Tok = o.Tok;
311762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
312d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    case CCOut:
313762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Register:
314762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Reg = o.Reg;
315762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
3168d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    case RegisterList:
3170f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    case DPRRegisterList:
3180f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    case SPRRegisterList:
31924d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling      Registers = o.Registers;
3208d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling      break;
321fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    case CoprocNum:
322fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    case CoprocReg:
323fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      Cop = o.Cop;
324fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      break;
325762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Immediate:
326762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Imm = o.Imm;
327762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
328706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    case MemBarrierOpt:
329706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      MBOpt = o.MBOpt;
330706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      break;
331762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Memory:
332762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Mem = o.Mem;
333762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
3347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    case PostIndexRegister:
3357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      PostIdxReg = o.PostIdxReg;
3367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      break;
337584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    case MSRMask:
338584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      MMask = o.MMask;
339584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      break;
340a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    case ProcIFlags:
341a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      IFlags = o.IFlags;
3420082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      break;
343580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    case ShifterImmediate:
344580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      ShifterImm = o.ShifterImm;
3450082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      break;
346e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    case ShiftedRegister:
347af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      RegShiftedReg = o.RegShiftedReg;
348e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      break;
34992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    case ShiftedImmediate:
350af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      RegShiftedImm = o.RegShiftedImm;
35192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      break;
3527e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    case RotateImmediate:
3537e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach      RotImm = o.RotImm;
3547e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach      break;
355293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    case BitfieldDescriptor:
356293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      Bitfield = o.Bitfield;
357293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      break;
358762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    }
359762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  }
36016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
361762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  /// getStartLoc - Get the location of the first token of this operand.
362762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc getStartLoc() const { return StartLoc; }
363762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  /// getEndLoc - Get the location of the last token of this operand.
364762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc getEndLoc() const { return EndLoc; }
365a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
3668462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  ARMCC::CondCodes getCondCode() const {
3678462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    assert(Kind == CondCode && "Invalid access!");
3688462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    return CC.Val;
3698462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  }
3708462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
371fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  unsigned getCoproc() const {
372fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    assert((Kind == CoprocNum || Kind == CoprocReg) && "Invalid access!");
373fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Cop.Val;
374fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
375fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
376a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  StringRef getToken() const {
377a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    assert(Kind == Token && "Invalid access!");
378a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return StringRef(Tok.Data, Tok.Length);
379a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
380a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
381a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  unsigned getReg() const {
3826aa49435994c33257b7588cac24671785d17fa6eBenjamin Kramer    assert((Kind == Register || Kind == CCOut) && "Invalid access!");
3837729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    return Reg.RegNum;
384a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
385a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
3865fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  const SmallVectorImpl<unsigned> &getRegList() const {
3870f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    assert((Kind == RegisterList || Kind == DPRRegisterList ||
3880f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling            Kind == SPRRegisterList) && "Invalid access!");
38924d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling    return Registers;
3908d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
3918d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
392cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  const MCExpr *getImm() const {
393cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    assert(Kind == Immediate && "Invalid access!");
394cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    return Imm.Val;
395cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  }
396cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby
397706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  ARM_MB::MemBOpt getMemBarrierOpt() const {
398706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    assert(Kind == MemBarrierOpt && "Invalid access!");
399706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    return MBOpt.Val;
400706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
401706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
402a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  ARM_PROC::IFlags getProcIFlags() const {
403a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    assert(Kind == ProcIFlags && "Invalid access!");
404a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    return IFlags.Val;
405a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
406a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
407584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  unsigned getMSRMask() const {
408584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    assert(Kind == MSRMask && "Invalid access!");
409584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return MMask.Val;
410584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
411584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
412fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  bool isCoprocNum() const { return Kind == CoprocNum; }
413fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  bool isCoprocReg() const { return Kind == CoprocReg; }
4148462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  bool isCondCode() const { return Kind == CondCode; }
415d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  bool isCCOut() const { return Kind == CCOut; }
4163483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  bool isImm() const { return Kind == Immediate; }
41772f39f8436848885176943b0ba985a7171145423Jim Grosbach  bool isImm0_1020s4() const {
41872f39f8436848885176943b0ba985a7171145423Jim Grosbach    if (Kind != Immediate)
41972f39f8436848885176943b0ba985a7171145423Jim Grosbach      return false;
42072f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
42172f39f8436848885176943b0ba985a7171145423Jim Grosbach    if (!CE) return false;
42272f39f8436848885176943b0ba985a7171145423Jim Grosbach    int64_t Value = CE->getValue();
42372f39f8436848885176943b0ba985a7171145423Jim Grosbach    return ((Value & 3) == 0) && Value >= 0 && Value <= 1020;
42472f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
42572f39f8436848885176943b0ba985a7171145423Jim Grosbach  bool isImm0_508s4() const {
42672f39f8436848885176943b0ba985a7171145423Jim Grosbach    if (Kind != Immediate)
42772f39f8436848885176943b0ba985a7171145423Jim Grosbach      return false;
42872f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
42972f39f8436848885176943b0ba985a7171145423Jim Grosbach    if (!CE) return false;
43072f39f8436848885176943b0ba985a7171145423Jim Grosbach    int64_t Value = CE->getValue();
43172f39f8436848885176943b0ba985a7171145423Jim Grosbach    return ((Value & 3) == 0) && Value >= 0 && Value <= 508;
43272f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
4336b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  bool isImm0_255() const {
4346b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (Kind != Immediate)
4356b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach      return false;
4366b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
4376b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (!CE) return false;
4386b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    int64_t Value = CE->getValue();
4396b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    return Value >= 0 && Value < 256;
4406b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
44183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  bool isImm0_7() const {
44283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (Kind != Immediate)
44383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach      return false;
44483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
44583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (!CE) return false;
44683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    int64_t Value = CE->getValue();
44783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    return Value >= 0 && Value < 8;
44883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
44983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  bool isImm0_15() const {
45083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (Kind != Immediate)
45183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach      return false;
45283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
45383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (!CE) return false;
45483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    int64_t Value = CE->getValue();
45583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    return Value >= 0 && Value < 16;
45683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
4577c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach  bool isImm0_31() const {
4587c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    if (Kind != Immediate)
4597c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach      return false;
4607c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
4617c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    if (!CE) return false;
4627c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    int64_t Value = CE->getValue();
4637c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    return Value >= 0 && Value < 32;
4647c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach  }
465f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  bool isImm1_16() const {
466f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    if (Kind != Immediate)
467f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach      return false;
468f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
469f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    if (!CE) return false;
470f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    int64_t Value = CE->getValue();
471f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    return Value > 0 && Value < 17;
472f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  }
4734a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  bool isImm1_32() const {
4744a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    if (Kind != Immediate)
4754a5ffb399f841783c201c599b88d576757f1922eJim Grosbach      return false;
4764a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
4774a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    if (!CE) return false;
4784a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    int64_t Value = CE->getValue();
4794a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    return Value > 0 && Value < 33;
4804a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  }
481fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  bool isImm0_65535() const {
482fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    if (Kind != Immediate)
483fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach      return false;
484fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
485fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    if (!CE) return false;
486fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    int64_t Value = CE->getValue();
487fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    return Value >= 0 && Value < 65536;
488fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  }
489ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  bool isImm0_65535Expr() const {
490ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    if (Kind != Immediate)
491ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach      return false;
492ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
493ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    // If it's not a constant expression, it'll generate a fixup and be
494ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    // handled later.
495ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    if (!CE) return true;
496ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    int64_t Value = CE->getValue();
497ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    return Value >= 0 && Value < 65536;
498ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
499ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach  bool isImm24bit() const {
500ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    if (Kind != Immediate)
501ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach      return false;
502ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
503ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    if (!CE) return false;
504ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    int64_t Value = CE->getValue();
505ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    return Value >= 0 && Value <= 0xffffff;
506ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach  }
50770939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach  bool isImmThumbSR() const {
50870939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    if (Kind != Immediate)
50970939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach      return false;
51070939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
51170939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    if (!CE) return false;
51270939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    int64_t Value = CE->getValue();
51370939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    return Value > 0 && Value < 33;
51470939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach  }
515f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  bool isPKHLSLImm() const {
516f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    if (Kind != Immediate)
517f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach      return false;
518f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
519f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    if (!CE) return false;
520f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int64_t Value = CE->getValue();
521f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return Value >= 0 && Value < 32;
522f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
523f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  bool isPKHASRImm() const {
524f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    if (Kind != Immediate)
525f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach      return false;
526f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
527f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    if (!CE) return false;
528f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int64_t Value = CE->getValue();
529f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return Value > 0 && Value <= 32;
530f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
5316bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  bool isARMSOImm() const {
5326bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    if (Kind != Immediate)
5336bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach      return false;
5346bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
5356bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    if (!CE) return false;
5366bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    int64_t Value = CE->getValue();
5376bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    return ARM_AM::getSOImmVal(Value) != -1;
5386bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  }
5396b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  bool isT2SOImm() const {
5406b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (Kind != Immediate)
5416b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach      return false;
5426b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
5436b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (!CE) return false;
5446b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    int64_t Value = CE->getValue();
5456b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    return ARM_AM::getT2SOImmVal(Value) != -1;
5466b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
547c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  bool isSetEndImm() const {
548c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    if (Kind != Immediate)
549c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach      return false;
550c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
551c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    if (!CE) return false;
552c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    int64_t Value = CE->getValue();
553c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return Value == 1 || Value == 0;
554c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
555b32e7844e9f79d2bd4ff34a1d19aba347f999abcBill Wendling  bool isReg() const { return Kind == Register; }
5568d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  bool isRegList() const { return Kind == RegisterList; }
5570f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  bool isDPRRegList() const { return Kind == DPRRegisterList; }
5580f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  bool isSPRRegList() const { return Kind == SPRRegisterList; }
55914b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  bool isToken() const { return Kind == Token; }
560706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; }
56114b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  bool isMemory() const { return Kind == Memory; }
562580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  bool isShifterImm() const { return Kind == ShifterImmediate; }
563af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach  bool isRegShiftedReg() const { return Kind == ShiftedRegister; }
564af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach  bool isRegShiftedImm() const { return Kind == ShiftedImmediate; }
5657e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  bool isRotImm() const { return Kind == RotateImmediate; }
566293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  bool isBitfield() const { return Kind == BitfieldDescriptor; }
567f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  bool isPostIdxRegShifted() const { return Kind == PostIndexRegister; }
568f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  bool isPostIdxReg() const {
569f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    return Kind == PostIndexRegister && PostIdxReg.ShiftTy == ARM_AM::no_shift;
570f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  }
5717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemNoOffset() const {
5727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Kind != Memory)
573ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      return false;
5747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // No offset of any kind.
5757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Mem.OffsetRegNum == 0 && Mem.OffsetImm == 0;
576ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
5777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isAddrMode2() const {
5787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Kind != Memory)
579ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return false;
5807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Check for register offset.
5817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Mem.OffsetRegNum) return true;
5827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-4095, 4095].
5837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!Mem.OffsetImm) return true;
5847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
5857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Val > -4096 && Val < 4096;
5867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
587039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  bool isAM2OffsetImm() const {
588039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (Kind != Immediate)
589039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach      return false;
590039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    // Immediate offset in range [-4095, 4095].
591039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
592039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (!CE) return false;
593039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    int64_t Val = CE->getValue();
594039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    return Val > -4096 && Val < 4096;
595039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  }
5962fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  bool isAddrMode3() const {
5972fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Kind != Memory)
5982fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      return false;
5992fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // No shifts are legal for AM3.
6002fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Mem.ShiftType != ARM_AM::no_shift) return false;
6012fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Check for register offset.
6022fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Mem.OffsetRegNum) return true;
6032fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Immediate offset in range [-255, 255].
6042fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (!Mem.OffsetImm) return true;
6052fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
6062fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    return Val > -256 && Val < 256;
6072fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
6082fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  bool isAM3Offset() const {
6092fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Kind != Immediate && Kind != PostIndexRegister)
6102fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      return false;
6112fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Kind == PostIndexRegister)
6122fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      return PostIdxReg.ShiftTy == ARM_AM::no_shift;
6132fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Immediate offset in range [-255, 255].
6142fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6152fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (!CE) return false;
6162fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    int64_t Val = CE->getValue();
617251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // Special case, #-0 is INT32_MIN.
618251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    return (Val > -256 && Val < 256) || Val == INT32_MIN;
6192fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
6207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isAddrMode5() const {
6217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Kind != Memory)
622ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return false;
6237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Check for register offset.
6247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Mem.OffsetRegNum) return false;
6257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-1020, 1020] and a multiple of 4.
6267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!Mem.OffsetImm) return true;
6277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
6287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Val >= -1020 && Val <= 1020 && ((Val & 3) == 0);
6297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
6307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemRegOffset() const {
6317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Kind != Memory || !Mem.OffsetRegNum)
632ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return false;
633ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    return true;
634ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  }
6357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemThumbRR() const {
6367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Thumb reg+reg addressing is simple. Just two registers, a base and
6377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // an offset. No shifts, negations or any other complicating factors.
6387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Kind != Memory || !Mem.OffsetRegNum || Mem.isNegative ||
6397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach        Mem.ShiftType != ARM_AM::no_shift)
64087f4f9a946549ad93046990a364ac5190333a7ebBill Wendling      return false;
64160f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    return isARMLowRegister(Mem.BaseRegNum) &&
64260f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach      (!Mem.OffsetRegNum || isARMLowRegister(Mem.OffsetRegNum));
64360f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  }
64460f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  bool isMemThumbRIs4() const {
64560f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    if (Kind != Memory || Mem.OffsetRegNum != 0 ||
64660f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach        !isARMLowRegister(Mem.BaseRegNum))
64760f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach      return false;
64860f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    // Immediate offset, multiple of 4 in range [0, 124].
64960f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    if (!Mem.OffsetImm) return true;
65060f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
651ecd858968384be029574d845eb098d357049e02eJim Grosbach    return Val >= 0 && Val <= 124 && (Val % 4) == 0;
652ecd858968384be029574d845eb098d357049e02eJim Grosbach  }
65338466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  bool isMemThumbRIs2() const {
65438466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    if (Kind != Memory || Mem.OffsetRegNum != 0 ||
65538466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach        !isARMLowRegister(Mem.BaseRegNum))
65638466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach      return false;
65738466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    // Immediate offset, multiple of 4 in range [0, 62].
65838466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    if (!Mem.OffsetImm) return true;
65938466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
66038466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    return Val >= 0 && Val <= 62 && (Val % 2) == 0;
66138466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  }
66248ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  bool isMemThumbRIs1() const {
66348ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    if (Kind != Memory || Mem.OffsetRegNum != 0 ||
66448ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach        !isARMLowRegister(Mem.BaseRegNum))
66548ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach      return false;
66648ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    // Immediate offset in range [0, 31].
66748ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    if (!Mem.OffsetImm) return true;
66848ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
66948ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    return Val >= 0 && Val <= 31;
67048ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  }
671ecd858968384be029574d845eb098d357049e02eJim Grosbach  bool isMemThumbSPI() const {
672ecd858968384be029574d845eb098d357049e02eJim Grosbach    if (Kind != Memory || Mem.OffsetRegNum != 0 || Mem.BaseRegNum != ARM::SP)
673ecd858968384be029574d845eb098d357049e02eJim Grosbach      return false;
674ecd858968384be029574d845eb098d357049e02eJim Grosbach    // Immediate offset, multiple of 4 in range [0, 1020].
675ecd858968384be029574d845eb098d357049e02eJim Grosbach    if (!Mem.OffsetImm) return true;
676ecd858968384be029574d845eb098d357049e02eJim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
677ecd858968384be029574d845eb098d357049e02eJim Grosbach    return Val >= 0 && Val <= 1020 && (Val % 4) == 0;
678505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  }
6797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemImm8Offset() const {
6807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Kind != Memory || Mem.OffsetRegNum != 0)
681f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling      return false;
6827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-255, 255].
6837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!Mem.OffsetImm) return true;
6847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
6857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Val > -256 && Val < 256;
686f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  }
6877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemImm12Offset() const {
68809176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // If we have an immediate that's not a constant, treat it as a label
68909176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // reference needing a fixup. If it is a constant, it's something else
69009176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // and we reject it.
69109176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    if (Kind == Immediate && !isa<MCConstantExpr>(getImm()))
69209176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      return true;
69309176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach
6947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Kind != Memory || Mem.OffsetRegNum != 0)
695ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling      return false;
6967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-4095, 4095].
6977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!Mem.OffsetImm) return true;
6987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
6997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Val > -4096 && Val < 4096;
7007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
7017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isPostIdxImm8() const {
7027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Kind != Immediate)
7037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return false;
7047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
705ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    if (!CE) return false;
7067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Val = CE->getValue();
7077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Val > -256 && Val < 256;
708ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  }
7097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
710584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  bool isMSRMask() const { return Kind == MSRMask; }
711a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  bool isProcIFlags() const { return Kind == ProcIFlags; }
7123483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
7133483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
71414b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    // Add as immediates when possible.  Null MCExpr = 0.
71514b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    if (Expr == 0)
71614b93851cc7611ae6c2000f1c162592ead954420Chris Lattner      Inst.addOperand(MCOperand::CreateImm(0));
71714b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
7183483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
7193483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    else
7203483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar      Inst.addOperand(MCOperand::CreateExpr(Expr));
7213483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  }
7223483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
7238462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  void addCondCodeOperands(MCInst &Inst, unsigned N) const {
724345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    assert(N == 2 && "Invalid number of operands!");
7258462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode())));
72604f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach    unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR;
72704f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegNum));
7288462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  }
7298462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
730fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  void addCoprocNumOperands(MCInst &Inst, unsigned N) const {
731fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
732fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
733fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
734fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
735fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  void addCoprocRegOperands(MCInst &Inst, unsigned N) const {
736fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
737fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
738fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
739fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
740d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  void addCCOutOperands(MCInst &Inst, unsigned N) const {
741d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
742d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Inst.addOperand(MCOperand::CreateReg(getReg()));
743d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  }
744d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach
745a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  void addRegOperands(MCInst &Inst, unsigned N) const {
746a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    assert(N == 1 && "Invalid number of operands!");
747a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    Inst.addOperand(MCOperand::CreateReg(getReg()));
748a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
749a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
750af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach  void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const {
751e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    assert(N == 3 && "Invalid number of operands!");
752af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    assert(isRegShiftedReg() && "addRegShiftedRegOperands() on non RegShiftedReg!");
753af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.SrcReg));
754af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.ShiftReg));
755e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Inst.addOperand(MCOperand::CreateImm(
756af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm)));
757e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
758e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
759af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach  void addRegShiftedImmOperands(MCInst &Inst, unsigned N) const {
760152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson    assert(N == 2 && "Invalid number of operands!");
761af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    assert(isRegShiftedImm() && "addRegShiftedImmOperands() on non RegShiftedImm!");
762af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegShiftedImm.SrcReg));
76392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Inst.addOperand(MCOperand::CreateImm(
764af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, RegShiftedImm.ShiftImm)));
76592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  }
76692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson
76792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson
768580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  void addShifterImmOperands(MCInst &Inst, unsigned N) const {
7690082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    assert(N == 1 && "Invalid number of operands!");
770580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Inst.addOperand(MCOperand::CreateImm((ShifterImm.isASR << 5) |
771580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach                                         ShifterImm.Imm));
7720082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  }
7730082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
77487f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  void addRegListOperands(MCInst &Inst, unsigned N) const {
7757729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    assert(N == 1 && "Invalid number of operands!");
7765fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    const SmallVectorImpl<unsigned> &RegList = getRegList();
7775fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<unsigned>::const_iterator
7787729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = RegList.begin(), E = RegList.end(); I != E; ++I)
7797729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      Inst.addOperand(MCOperand::CreateReg(*I));
78087f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  }
78187f4f9a946549ad93046990a364ac5190333a7ebBill Wendling
7820f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  void addDPRRegListOperands(MCInst &Inst, unsigned N) const {
7830f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    addRegListOperands(Inst, N);
7840f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  }
7850f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
7860f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  void addSPRRegListOperands(MCInst &Inst, unsigned N) const {
7870f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    addRegListOperands(Inst, N);
7880f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  }
7890f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
7907e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  void addRotImmOperands(MCInst &Inst, unsigned N) const {
7917e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
7927e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    // Encoded as val>>3. The printer handles display as 8, 16, 24.
7937e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(RotImm.Imm >> 3));
7947e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
7957e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
796293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  void addBitfieldOperands(MCInst &Inst, unsigned N) const {
797293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
798293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    // Munge the lsb/width into a bitfield mask.
799293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    unsigned lsb = Bitfield.LSB;
800293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    unsigned width = Bitfield.Width;
801293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    // Make a 32-bit mask w/ the referenced bits clear and all other bits set.
802293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >>
803293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach                      (32 - (lsb + width)));
804293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Mask));
805293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
806293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
8073483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  void addImmOperands(MCInst &Inst, unsigned N) const {
8086b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
8096b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    addExpr(Inst, getImm());
8106b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
8116b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach
81272f39f8436848885176943b0ba985a7171145423Jim Grosbach  void addImm0_1020s4Operands(MCInst &Inst, unsigned N) const {
81372f39f8436848885176943b0ba985a7171145423Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
81472f39f8436848885176943b0ba985a7171145423Jim Grosbach    // The immediate is scaled by four in the encoding and is stored
81572f39f8436848885176943b0ba985a7171145423Jim Grosbach    // in the MCInst as such. Lop off the low two bits here.
81672f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
81772f39f8436848885176943b0ba985a7171145423Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4));
81872f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
81972f39f8436848885176943b0ba985a7171145423Jim Grosbach
82072f39f8436848885176943b0ba985a7171145423Jim Grosbach  void addImm0_508s4Operands(MCInst &Inst, unsigned N) const {
82172f39f8436848885176943b0ba985a7171145423Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
82272f39f8436848885176943b0ba985a7171145423Jim Grosbach    // The immediate is scaled by four in the encoding and is stored
82372f39f8436848885176943b0ba985a7171145423Jim Grosbach    // in the MCInst as such. Lop off the low two bits here.
82472f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
82572f39f8436848885176943b0ba985a7171145423Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4));
82672f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
82772f39f8436848885176943b0ba985a7171145423Jim Grosbach
8286b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  void addImm0_255Operands(MCInst &Inst, unsigned N) const {
8296b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
8306b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    addExpr(Inst, getImm());
8316b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
8326b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach
83383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  void addImm0_7Operands(MCInst &Inst, unsigned N) const {
83483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
83583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    addExpr(Inst, getImm());
83683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
83783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach
83883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  void addImm0_15Operands(MCInst &Inst, unsigned N) const {
8397c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
8407c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    addExpr(Inst, getImm());
8417c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach  }
8427c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach
8437c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach  void addImm0_31Operands(MCInst &Inst, unsigned N) const {
84483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
84583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    addExpr(Inst, getImm());
84683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
84783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach
848f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  void addImm1_16Operands(MCInst &Inst, unsigned N) const {
849f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    assert(N == 1 && "Invalid number of operands!");
850f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    // The constant encodes as the immediate-1, and we store in the instruction
851f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    // the bits as encoded, so subtract off one here.
852f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
853f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1));
854f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  }
855f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach
8564a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  void addImm1_32Operands(MCInst &Inst, unsigned N) const {
8574a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
8584a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    // The constant encodes as the immediate-1, and we store in the instruction
8594a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    // the bits as encoded, so subtract off one here.
8604a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
8614a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1));
8624a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  }
8634a5ffb399f841783c201c599b88d576757f1922eJim Grosbach
864fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  void addImm0_65535Operands(MCInst &Inst, unsigned N) const {
865fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    assert(N == 1 && "Invalid number of operands!");
866fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    addExpr(Inst, getImm());
867fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  }
868fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach
869ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  void addImm0_65535ExprOperands(MCInst &Inst, unsigned N) const {
870ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
871ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    addExpr(Inst, getImm());
872ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach  }
873ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach
874ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach  void addImm24bitOperands(MCInst &Inst, unsigned N) const {
875ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    assert(N == 1 && "Invalid number of operands!");
876ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    addExpr(Inst, getImm());
87770939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach  }
87870939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach
87970939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach  void addImmThumbSROperands(MCInst &Inst, unsigned N) const {
88070939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
88170939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    // The constant encodes as the immediate, except for 32, which encodes as
88270939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    // zero.
88370939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
88470939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    unsigned Imm = CE->getValue();
88570939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    Inst.addOperand(MCOperand::CreateImm((Imm == 32 ? 0 : Imm)));
886ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
887ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
888f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  void addPKHLSLImmOperands(MCInst &Inst, unsigned N) const {
889f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
890f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    addExpr(Inst, getImm());
891f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
892f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
893f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  void addPKHASRImmOperands(MCInst &Inst, unsigned N) const {
894f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
895f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    // An ASR value of 32 encodes as 0, so that's how we want to add it to
896f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    // the instruction as well.
897f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
898f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int Val = CE->getValue();
899f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val == 32 ? 0 : Val));
900f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
901f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
9026bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  void addARMSOImmOperands(MCInst &Inst, unsigned N) const {
9036bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    assert(N == 1 && "Invalid number of operands!");
9046bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    addExpr(Inst, getImm());
9056bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  }
9066bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach
9076b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  void addT2SOImmOperands(MCInst &Inst, unsigned N) const {
9083483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    assert(N == 1 && "Invalid number of operands!");
9093483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    addExpr(Inst, getImm());
9103483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  }
91116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
912c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  void addSetEndImmOperands(MCInst &Inst, unsigned N) const {
913c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
914c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    addExpr(Inst, getImm());
915c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
916c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach
917706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const {
918706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
919706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt())));
920706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
921706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
9227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const {
9237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
9247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
925505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  }
926505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes
9277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addAddrMode2Operands(MCInst &Inst, unsigned N) const {
9287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 3 && "Invalid number of operands!");
9297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0;
9307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!Mem.OffsetRegNum) {
9317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
9327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // Special case for #-0
9337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      if (Val == INT32_MIN) Val = 0;
9347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      if (Val < 0) Val = -Val;
9357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
9367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    } else {
9377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // For register offset, we encode the shift type and negation flag
9387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // here.
9397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Val = ARM_AM::getAM2Opc(Mem.isNegative ? ARM_AM::sub : ARM_AM::add,
940dd32ba337aab88c215108ca8bf4a0267fce1e773Jim Grosbach                              Mem.ShiftImm, Mem.ShiftType);
941ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    }
9427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
9437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum));
9447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
945ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
946ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
947039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  void addAM2OffsetImmOperands(MCInst &Inst, unsigned N) const {
948039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
949039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
950039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    assert(CE && "non-constant AM2OffsetImm operand!");
951039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    int32_t Val = CE->getValue();
952039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
953039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    // Special case for #-0
954039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (Val == INT32_MIN) Val = 0;
955039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (Val < 0) Val = -Val;
956039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
957039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(0));
958039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
959039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  }
960039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach
9612fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  void addAddrMode3Operands(MCInst &Inst, unsigned N) const {
9622fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    assert(N == 3 && "Invalid number of operands!");
9632fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0;
9642fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (!Mem.OffsetRegNum) {
9652fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
9662fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      // Special case for #-0
9672fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      if (Val == INT32_MIN) Val = 0;
9682fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      if (Val < 0) Val = -Val;
9692fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      Val = ARM_AM::getAM3Opc(AddSub, Val);
9702fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    } else {
9712fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      // For register offset, we encode the shift type and negation flag
9722fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      // here.
9732fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      Val = ARM_AM::getAM3Opc(Mem.isNegative ? ARM_AM::sub : ARM_AM::add, 0);
9742fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    }
9752fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
9762fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum));
9772fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
9782fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
9792fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
9802fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  void addAM3OffsetOperands(MCInst &Inst, unsigned N) const {
9812fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
9822fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Kind == PostIndexRegister) {
9832fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      int32_t Val =
9842fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach        ARM_AM::getAM3Opc(PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub, 0);
9852fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
9862fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(Val));
987251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return;
9882fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    }
9892fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
9902fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Constant offset.
9912fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    const MCConstantExpr *CE = static_cast<const MCConstantExpr*>(getImm());
9922fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    int32_t Val = CE->getValue();
9932fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
9942fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Special case for #-0
9952fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Val == INT32_MIN) Val = 0;
9962fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Val < 0) Val = -Val;
997251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Val = ARM_AM::getAM3Opc(AddSub, Val);
9982fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(0));
9992fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
10002fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
10012fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
10027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addAddrMode5Operands(MCInst &Inst, unsigned N) const {
10037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
10047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // The lower two bits are always zero and as such are not encoded.
10057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() / 4 : 0;
10067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
10077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Special case for #-0
10087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Val == INT32_MIN) Val = 0;
10097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Val < 0) Val = -Val;
10107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Val = ARM_AM::getAM5Opc(AddSub, Val);
10117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
10127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
10137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
10147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
10157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemImm8OffsetOperands(MCInst &Inst, unsigned N) const {
10167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
10177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0;
10187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
10197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1020ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  }
1021ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
10227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const {
10237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
102409176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // If this is an immediate, it's a label reference.
102509176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    if (Kind == Immediate) {
102609176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      addExpr(Inst, getImm());
102709176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(0));
102809176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      return;
102909176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    }
103009176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach
103109176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // Otherwise, it's a normal memory reg+offset.
10327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0;
10337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
10347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
10357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
103692b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
10377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const {
10387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 3 && "Invalid number of operands!");
10397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    unsigned Val = ARM_AM::getAM2Opc(Mem.isNegative ? ARM_AM::sub : ARM_AM::add,
10400d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach                                     Mem.ShiftImm, Mem.ShiftType);
10417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
10427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum));
10437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
10447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
1045d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar
10467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemThumbRROperands(MCInst &Inst, unsigned N) const {
10477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
10487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
10497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum));
105014b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  }
10513483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
105260f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  void addMemThumbRIs4Operands(MCInst &Inst, unsigned N) const {
105360f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
105460f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    int64_t Val = Mem.OffsetImm ? (Mem.OffsetImm->getValue() / 4) : 0;
105560f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
105660f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
105748ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  }
105848ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach
105938466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  void addMemThumbRIs2Operands(MCInst &Inst, unsigned N) const {
106038466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
106138466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    int64_t Val = Mem.OffsetImm ? (Mem.OffsetImm->getValue() / 2) : 0;
106238466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
106338466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
106438466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  }
106538466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach
106648ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  void addMemThumbRIs1Operands(MCInst &Inst, unsigned N) const {
106748ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
106848ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    int64_t Val = Mem.OffsetImm ? (Mem.OffsetImm->getValue()) : 0;
106948ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
107048ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
107160f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  }
107260f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach
1073ecd858968384be029574d845eb098d357049e02eJim Grosbach  void addMemThumbSPIOperands(MCInst &Inst, unsigned N) const {
1074ecd858968384be029574d845eb098d357049e02eJim Grosbach    assert(N == 2 && "Invalid number of operands!");
1075ecd858968384be029574d845eb098d357049e02eJim Grosbach    int64_t Val = Mem.OffsetImm ? (Mem.OffsetImm->getValue() / 4) : 0;
1076ecd858968384be029574d845eb098d357049e02eJim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
1077ecd858968384be029574d845eb098d357049e02eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1078ecd858968384be029574d845eb098d357049e02eJim Grosbach  }
1079ecd858968384be029574d845eb098d357049e02eJim Grosbach
10807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const {
10817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
10827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
10837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(CE && "non-constant post-idx-imm8 operand!");
10847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int Imm = CE->getValue();
10857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    bool isAdd = Imm >= 0;
10867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Imm = (Imm < 0 ? -Imm : Imm) | (int)isAdd << 8;
10877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm));
1088f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  }
1089ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
10907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addPostIdxRegOperands(MCInst &Inst, unsigned N) const {
10917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
10927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
1093f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(PostIdxReg.isAdd));
1094f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  }
1095f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach
1096f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const {
1097f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1098f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
1099f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    // The sign, shift type, and shift amount are encoded in a single operand
1100f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    // using the AM2 encoding helpers.
1101f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub;
1102f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm,
1103f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                     PostIdxReg.ShiftTy);
1104f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm));
1105ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  }
1106ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
1107584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  void addMSRMaskOperands(MCInst &Inst, unsigned N) const {
1108584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1109584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask())));
1110584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
1111584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1112a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  void addProcIFlagsOperands(MCInst &Inst, unsigned N) const {
1113a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1114a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags())));
1115a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
1116a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1117b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbach  virtual void print(raw_ostream &OS) const;
1118b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar
11193a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) {
11203a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(CondCode);
1121345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->CC.Val = CC;
1122345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->StartLoc = S;
1123345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->EndLoc = S;
11243a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
1125345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  }
1126345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
1127fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) {
1128fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(CoprocNum);
1129fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->Cop.Val = CopVal;
1130fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->StartLoc = S;
1131fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->EndLoc = S;
1132fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Op;
1133fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
1134fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1135fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) {
1136fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(CoprocReg);
1137fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->Cop.Val = CopVal;
1138fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->StartLoc = S;
1139fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->EndLoc = S;
1140fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Op;
1141fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
1142fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1143d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) {
1144d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    ARMOperand *Op = new ARMOperand(CCOut);
1145d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->Reg.RegNum = RegNum;
1146d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->StartLoc = S;
1147d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->EndLoc = S;
1148d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    return Op;
1149d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  }
1150d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach
11513a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateToken(StringRef Str, SMLoc S) {
11523a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(Token);
1153762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Tok.Data = Str.data();
1154762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Tok.Length = Str.size();
1155762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
1156762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = S;
11573a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
1158a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
1159a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
116050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
11613a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(Register);
1162762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Reg.RegNum = RegNum;
1163762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
1164762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
11653a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
1166a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
1167a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1168e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  static ARMOperand *CreateShiftedRegister(ARM_AM::ShiftOpc ShTy,
1169e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned SrcReg,
1170e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned ShiftReg,
1171e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned ShiftImm,
1172e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           SMLoc S, SMLoc E) {
1173e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    ARMOperand *Op = new ARMOperand(ShiftedRegister);
1174af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.ShiftTy = ShTy;
1175af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.SrcReg = SrcReg;
1176af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.ShiftReg = ShiftReg;
1177af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.ShiftImm = ShiftImm;
1178e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->StartLoc = S;
1179e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->EndLoc = E;
1180e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    return Op;
1181e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
1182e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
118392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  static ARMOperand *CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy,
118492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            unsigned SrcReg,
118592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            unsigned ShiftImm,
118692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            SMLoc S, SMLoc E) {
118792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    ARMOperand *Op = new ARMOperand(ShiftedImmediate);
1188af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedImm.ShiftTy = ShTy;
1189af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedImm.SrcReg = SrcReg;
1190af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedImm.ShiftImm = ShiftImm;
119192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Op->StartLoc = S;
119292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Op->EndLoc = E;
119392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    return Op;
119492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  }
119592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson
1196580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  static ARMOperand *CreateShifterImm(bool isASR, unsigned Imm,
11970082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                   SMLoc S, SMLoc E) {
1198580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    ARMOperand *Op = new ARMOperand(ShifterImmediate);
1199580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Op->ShifterImm.isASR = isASR;
1200580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Op->ShifterImm.Imm = Imm;
12010082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->StartLoc = S;
12020082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->EndLoc = E;
12030082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    return Op;
12040082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  }
12050082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
12067e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  static ARMOperand *CreateRotImm(unsigned Imm, SMLoc S, SMLoc E) {
12077e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    ARMOperand *Op = new ARMOperand(RotateImmediate);
12087e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Op->RotImm.Imm = Imm;
12097e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Op->StartLoc = S;
12107e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Op->EndLoc = E;
12117e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return Op;
12127e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
12137e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
1214293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  static ARMOperand *CreateBitfield(unsigned LSB, unsigned Width,
1215293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach                                    SMLoc S, SMLoc E) {
1216293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    ARMOperand *Op = new ARMOperand(BitfieldDescriptor);
1217293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->Bitfield.LSB = LSB;
1218293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->Bitfield.Width = Width;
1219293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->StartLoc = S;
1220293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->EndLoc = E;
1221293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return Op;
1222293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
1223293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
12247729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  static ARMOperand *
12255fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs,
1226cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay                SMLoc StartLoc, SMLoc EndLoc) {
12270f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    KindTy Kind = RegisterList;
12280f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
1229275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng    if (llvm::ARMMCRegisterClasses[ARM::DPRRegClassID].
1230275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng        contains(Regs.front().first))
12310f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling      Kind = DPRRegisterList;
1232275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng    else if (llvm::ARMMCRegisterClasses[ARM::SPRRegClassID].
1233275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng             contains(Regs.front().first))
12340f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling      Kind = SPRRegisterList;
12350f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
12360f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    ARMOperand *Op = new ARMOperand(Kind);
12375fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator
12387729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = Regs.begin(), E = Regs.end(); I != E; ++I)
123924d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling      Op->Registers.push_back(I->first);
1240cb21d1c9fd1cf53f063183f7eb28af7fa4052ef0Bill Wendling    array_pod_sort(Op->Registers.begin(), Op->Registers.end());
1241cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay    Op->StartLoc = StartLoc;
1242cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay    Op->EndLoc = EndLoc;
12438d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    return Op;
12448d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
12458d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
12463a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
12473a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(Immediate);
1248762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Imm.Val = Val;
1249762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
1250762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
12513a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
1252cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  }
1253cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby
12547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  static ARMOperand *CreateMem(unsigned BaseRegNum,
12557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               const MCConstantExpr *OffsetImm,
12567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               unsigned OffsetRegNum,
12577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               ARM_AM::ShiftOpc ShiftType,
12580d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach                               unsigned ShiftImm,
12597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               bool isNegative,
12603a69756e392942bc522193f38d7f33958ed3b131Chris Lattner                               SMLoc S, SMLoc E) {
12613a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(Memory);
1262762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.BaseRegNum = BaseRegNum;
12637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->Mem.OffsetImm = OffsetImm;
12647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->Mem.OffsetRegNum = OffsetRegNum;
1265762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.ShiftType = ShiftType;
12660d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach    Op->Mem.ShiftImm = ShiftImm;
12677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->Mem.isNegative = isNegative;
12687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->StartLoc = S;
12697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->EndLoc = E;
12707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Op;
12717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
127216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
1273f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  static ARMOperand *CreatePostIdxReg(unsigned RegNum, bool isAdd,
1274f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                      ARM_AM::ShiftOpc ShiftTy,
1275f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                      unsigned ShiftImm,
12767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                      SMLoc S, SMLoc E) {
12777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    ARMOperand *Op = new ARMOperand(PostIndexRegister);
12787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->PostIdxReg.RegNum = RegNum;
1279f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Op->PostIdxReg.isAdd = isAdd;
1280f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Op->PostIdxReg.ShiftTy = ShiftTy;
1281f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Op->PostIdxReg.ShiftImm = ShiftImm;
1282762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
1283762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
12843a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
1285a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
1286706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
1287706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) {
1288706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(MemBarrierOpt);
1289706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->MBOpt.Val = Opt;
1290706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->StartLoc = S;
1291706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->EndLoc = S;
1292706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    return Op;
1293706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
1294a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1295a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) {
1296a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(ProcIFlags);
1297a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->IFlags.Val = IFlags;
1298a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->StartLoc = S;
1299a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->EndLoc = S;
1300a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    return Op;
1301a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
1302584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1303584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) {
1304584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(MSRMask);
1305584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->MMask.Val = MMask;
1306584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->StartLoc = S;
1307584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->EndLoc = S;
1308584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return Op;
1309584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
1310a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby};
1311a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1312a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace.
1313a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1314b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbachvoid ARMOperand::print(raw_ostream &OS) const {
1315fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  switch (Kind) {
1316fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case CondCode:
13176a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar    OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">";
1318fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
1319d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  case CCOut:
1320d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    OS << "<ccout " << getReg() << ">";
1321d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    break;
1322fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  case CoprocNum:
1323fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    OS << "<coprocessor number: " << getCoproc() << ">";
1324fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    break;
1325fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  case CoprocReg:
1326fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    OS << "<coprocessor register: " << getCoproc() << ">";
1327fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    break;
1328584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  case MSRMask:
1329584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    OS << "<mask: " << getMSRMask() << ">";
1330584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    break;
1331fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Immediate:
1332fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    getImm()->print(OS);
1333fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
1334706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  case MemBarrierOpt:
1335706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">";
1336706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    break;
1337fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Memory:
13386ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    OS << "<memory "
13397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach       << " base:" << Mem.BaseRegNum;
13406ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    OS << ">";
1341fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
13427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  case PostIndexRegister:
1343f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    OS << "post-idx register " << (PostIdxReg.isAdd ? "" : "-")
1344f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach       << PostIdxReg.RegNum;
1345f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    if (PostIdxReg.ShiftTy != ARM_AM::no_shift)
1346f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      OS << ARM_AM::getShiftOpcStr(PostIdxReg.ShiftTy) << " "
1347f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach         << PostIdxReg.ShiftImm;
1348f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    OS << ">";
13497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    break;
1350a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  case ProcIFlags: {
1351a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    OS << "<ARM_PROC::";
1352a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned IFlags = getProcIFlags();
1353a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    for (int i=2; i >= 0; --i)
1354a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      if (IFlags & (1 << i))
1355a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes        OS << ARM_PROC::IFlagsToString(1 << i);
1356a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    OS << ">";
1357a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    break;
1358a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
1359fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Register:
136050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    OS << "<register " << getReg() << ">";
1361fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
1362580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  case ShifterImmediate:
1363580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl")
1364580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach       << " #" << ShifterImm.Imm << ">";
1365e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    break;
1366e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  case ShiftedRegister:
136792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    OS << "<so_reg_reg "
1368af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach       << RegShiftedReg.SrcReg
1369af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach       << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedReg.ShiftImm))
1370af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach       << ", " << RegShiftedReg.ShiftReg << ", "
1371af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach       << ARM_AM::getSORegOffset(RegShiftedReg.ShiftImm)
1372e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach       << ">";
13730082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    break;
137492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  case ShiftedImmediate:
137592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    OS << "<so_reg_imm "
1376af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach       << RegShiftedImm.SrcReg
1377af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach       << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedImm.ShiftImm))
1378af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach       << ", " << ARM_AM::getSORegOffset(RegShiftedImm.ShiftImm)
137992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson       << ">";
138092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    break;
13817e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  case RotateImmediate:
13827e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    OS << "<ror " << " #" << (RotImm.Imm * 8) << ">";
13837e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    break;
1384293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  case BitfieldDescriptor:
1385293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    OS << "<bitfield " << "lsb: " << Bitfield.LSB
1386293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach       << ", width: " << Bitfield.Width << ">";
1387293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    break;
13880f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  case RegisterList:
13890f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  case DPRRegisterList:
13900f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  case SPRRegisterList: {
13918d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    OS << "<register_list ";
13928d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
13935fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    const SmallVectorImpl<unsigned> &RegList = getRegList();
13945fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<unsigned>::const_iterator
13957729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = RegList.begin(), E = RegList.end(); I != E; ) {
13967729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      OS << *I;
13977729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      if (++I < E) OS << ", ";
13988d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    }
13998d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
14008d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    OS << ">";
14018d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    break;
14028d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
1403fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Token:
1404fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    OS << "'" << getToken() << "'";
1405fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
1406fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  }
1407fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar}
14083483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
14093483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions
14103483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// {
14113483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
14123483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name);
14133483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
14143483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// }
14153483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
141669df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilsonbool ARMAsmParser::ParseRegister(unsigned &RegNo,
141769df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson                                 SMLoc &StartLoc, SMLoc &EndLoc) {
14181355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  RegNo = tryParseRegister();
1419bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky
1420bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky  return (RegNo == (unsigned)-1);
1421bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky}
1422bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky
14239c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name.  The token must be an Identifier when called,
1424e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// and if it is a register name the token is eaten and the register number is
1425e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// returned.  Otherwise return -1.
14263a69756e392942bc522193f38d7f33958ed3b131Chris Lattner///
14271355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachint ARMAsmParser::tryParseRegister() {
142818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
14297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) return -1;
1430d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
1431a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  // FIXME: Validate register for the current architecture; we have to do
1432a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  // validation later, so maybe there is no need for this here.
14330c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  std::string upperCase = Tok.getString().str();
14340c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  std::string lowerCase = LowercaseString(upperCase);
14350c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  unsigned RegNum = MatchRegisterName(lowerCase);
14360c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  if (!RegNum) {
14370c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson    RegNum = StringSwitch<unsigned>(lowerCase)
14380c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r13", ARM::SP)
14390c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r14", ARM::LR)
14400c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r15", ARM::PC)
14410c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("ip", ARM::R12)
14420c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Default(0);
14430c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  }
14440c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  if (!RegNum) return -1;
144569df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson
1446b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat identifier token.
1447e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  return RegNum;
1448e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner}
1449d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
145019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// Try to parse a shifter  (e.g., "lsl <amt>"). On success, return 0.
145119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// If a recoverable error occurs, return 1. If an irrecoverable error
145219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// occurs, return -1. An irrecoverable error is one where tokens have been
145319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// consumed in the process of trying to parse the shifter (i.e., when it is
145419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// indeed a shifter operand, but malformed).
14550d87ec21d79c8622733b8367aa41067169602480Jim Grosbachint ARMAsmParser::tryParseShiftRegister(
14560082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
14570082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  SMLoc S = Parser.getTok().getLoc();
14580082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  const AsmToken &Tok = Parser.getTok();
14590082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
14600082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
14610082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  std::string upperCase = Tok.getString().str();
14620082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  std::string lowerCase = LowercaseString(upperCase);
14630082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase)
14640082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("lsl", ARM_AM::lsl)
14650082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("lsr", ARM_AM::lsr)
14660082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("asr", ARM_AM::asr)
14670082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("ror", ARM_AM::ror)
14680082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("rrx", ARM_AM::rrx)
14690082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Default(ARM_AM::no_shift);
14700082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
14710082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  if (ShiftTy == ARM_AM::no_shift)
147219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    return 1;
14730082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
1474e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  Parser.Lex(); // Eat the operator.
1475e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
1476e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // The source register for the shift has already been added to the
1477e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // operand list, so we need to pop it off and combine it into the shifted
1478e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // register operand instead.
1479eac0796542d098caa371856d545faa6cdab5aad3Benjamin Kramer  OwningPtr<ARMOperand> PrevOp((ARMOperand*)Operands.pop_back_val());
1480e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  if (!PrevOp->isReg())
1481e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    return Error(PrevOp->getStartLoc(), "shift must be of a register");
1482e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int SrcReg = PrevOp->getReg();
1483e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int64_t Imm = 0;
1484e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int ShiftReg = 0;
1485e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  if (ShiftTy == ARM_AM::rrx) {
1486e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // RRX Doesn't have an explicit shift amount. The encoder expects
1487e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // the shift register to be the same as the source register. Seems odd,
1488e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // but OK.
1489e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    ShiftReg = SrcReg;
1490e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  } else {
1491e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // Figure out if this is shifted by a constant or a register (for non-RRX).
1492e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    if (Parser.getTok().is(AsmToken::Hash)) {
1493e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      Parser.Lex(); // Eat hash.
1494e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      SMLoc ImmLoc = Parser.getTok().getLoc();
1495e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      const MCExpr *ShiftExpr = 0;
149619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (getParser().ParseExpression(ShiftExpr)) {
149719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "invalid immediate shift value");
149819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
149919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
1500e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // The expression must be evaluatable as an immediate.
1501e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr);
150219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (!CE) {
150319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "invalid immediate shift value");
150419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
150519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
1506e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // Range check the immediate.
1507e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // lsl, ror: 0 <= imm <= 31
1508e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // lsr, asr: 0 <= imm <= 32
1509e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      Imm = CE->getValue();
1510e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      if (Imm < 0 ||
1511e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach          ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) ||
1512e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach          ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) {
151319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "immediate shift value out of range");
151419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
1515e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      }
1516e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    } else if (Parser.getTok().is(AsmToken::Identifier)) {
15171355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach      ShiftReg = tryParseRegister();
1518e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      SMLoc L = Parser.getTok().getLoc();
151919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (ShiftReg == -1) {
152019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error (L, "expected immediate or register in shift operand");
152119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
152219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
152319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    } else {
152419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      Error (Parser.getTok().getLoc(),
1525e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                    "expected immediate or register in shift operand");
152619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      return -1;
152719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    }
1528e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
1529e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
153092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  if (ShiftReg && ShiftTy != ARM_AM::rrx)
153192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg,
1532af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach                                                         ShiftReg, Imm,
15330082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                               S, Parser.getTok().getLoc()));
153492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  else
153592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm,
153692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                               S, Parser.getTok().getLoc()));
15370082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
153819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  return 0;
15390082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson}
15400082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
15410082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
154250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// Try to parse a register name.  The token must be an Identifier when called.
154350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// If it's a register, an AsmOperand is created. Another AsmOperand is created
154450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// if there is a "writeback". 'true' if it's not a register.
1545e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner///
1546e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// TODO this is likely to change to allow different register types and or to
1547e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// parse for a specific register type.
154850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
15491355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachtryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1550e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  SMLoc S = Parser.getTok().getLoc();
15511355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  int RegNo = tryParseRegister();
1552e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  if (RegNo == -1)
155350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
1554d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
155550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc()));
1556a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1557e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  const AsmToken &ExclaimTok = Parser.getTok();
1558e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  if (ExclaimTok.is(AsmToken::Exclaim)) {
155950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(),
156050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling                                               ExclaimTok.getLoc()));
1561e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner    Parser.Lex(); // Eat exclaim token
156299e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby  }
156399e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby
156450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  return false;
1565a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
1566a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1567fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// MatchCoprocessorOperandName - Try to parse an coprocessor related
1568fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// instruction with a symbolic operand name. Example: "p1", "p7", "c3",
1569fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// "c5", ...
1570fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopesstatic int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) {
1571e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  // Use the same layout as the tablegen'erated register name matcher. Ugly,
1572e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  // but efficient.
1573e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  switch (Name.size()) {
1574e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  default: break;
1575e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  case 2:
1576fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    if (Name[0] != CoprocOp)
1577e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson      return -1;
1578e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    switch (Name[1]) {
1579e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    default:  return -1;
1580e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '0': return 0;
1581e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '1': return 1;
1582e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '2': return 2;
1583e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '3': return 3;
1584e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '4': return 4;
1585e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '5': return 5;
1586e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '6': return 6;
1587e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '7': return 7;
1588e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '8': return 8;
1589e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '9': return 9;
1590e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    }
1591e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    break;
1592e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  case 3:
1593fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    if (Name[0] != CoprocOp || Name[1] != '1')
1594e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson      return -1;
1595e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    switch (Name[2]) {
1596e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    default:  return -1;
1597e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '0': return 10;
1598e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '1': return 11;
1599e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '2': return 12;
1600e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '3': return 13;
1601e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '4': return 14;
1602e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '5': return 15;
1603e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    }
1604e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    break;
1605e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  }
1606e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1607e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  return -1;
1608e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson}
1609e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
161043904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocNumOperand - Try to parse an coprocessor number operand. The
1611fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor
1612fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list.
1613f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
161443904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1615e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  SMLoc S = Parser.getTok().getLoc();
1616e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  const AsmToken &Tok = Parser.getTok();
1617e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1618e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1619fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  int Num = MatchCoprocessorOperandName(Tok.getString(), 'p');
1620e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  if (Num == -1)
1621f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
1622e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1623e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  Parser.Lex(); // Eat identifier token.
1624fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateCoprocNum(Num, S));
1625f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
1626fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes}
1627fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
162843904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocRegOperand - Try to parse an coprocessor register operand. The
1629fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor
1630fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list.
1631f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
163243904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1633fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
1634fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
1635fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1636fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1637fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c');
1638fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  if (Reg == -1)
1639f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
1640fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1641fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
1642fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S));
1643f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
1644e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson}
1645e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1646c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// Parse a register list, return it if successful else return null.  The first
1647c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// token must be a '{' when called.
164850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
16491355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachparseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
165018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  assert(Parser.getTok().is(AsmToken::LCurly) &&
1651a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling         "Token is not a Left Curly Brace");
1652e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  SMLoc S = Parser.getTok().getLoc();
165316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
16547729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  // Read the rest of the registers in the list.
16557729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  unsigned PrevRegNum = 0;
16565fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  SmallVector<std::pair<unsigned, SMLoc>, 32> Registers;
1657d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
16587729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  do {
1659e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    bool IsRange = Parser.getTok().is(AsmToken::Minus);
16607729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    Parser.Lex(); // Eat non-identifier token.
1661d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
166218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &RegTok = Parser.getTok();
1663d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby    SMLoc RegLoc = RegTok.getLoc();
1664c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    if (RegTok.isNot(AsmToken::Identifier)) {
1665c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner      Error(RegLoc, "register expected");
166650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
1667c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    }
1668e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
16691355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    int RegNum = tryParseRegister();
1670c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    if (RegNum == -1) {
1671c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner      Error(RegLoc, "register expected");
167250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
1673c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    }
1674d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
1675e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    if (IsRange) {
1676e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      int Reg = PrevRegNum;
1677e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      do {
1678e717610f53e0465cde198536561a3c00ce29d59fBill Wendling        ++Reg;
1679e717610f53e0465cde198536561a3c00ce29d59fBill Wendling        Registers.push_back(std::make_pair(Reg, RegLoc));
1680e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      } while (Reg != RegNum);
1681e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    } else {
1682e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      Registers.push_back(std::make_pair(RegNum, RegLoc));
1683e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    }
1684e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
1685e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    PrevRegNum = RegNum;
16867729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  } while (Parser.getTok().is(AsmToken::Comma) ||
16877729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           Parser.getTok().is(AsmToken::Minus));
1688e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
1689e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  // Process the right curly brace of the list.
169018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &RCurlyTok = Parser.getTok();
1691c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner  if (RCurlyTok.isNot(AsmToken::RCurly)) {
1692c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    Error(RCurlyTok.getLoc(), "'}' expected");
169350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
1694c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner  }
1695d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
1696e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  SMLoc E = RCurlyTok.getLoc();
1697e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  Parser.Lex(); // Eat right curly brace token.
169803f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach
1699e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  // Verify the register list.
17008e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling  bool EmittedWarning = false;
170111e03e7c2d0c163e54b911ad1e665616dc0bcc8cJim Grosbach  unsigned HighRegNum = 0;
170211e03e7c2d0c163e54b911ad1e665616dc0bcc8cJim Grosbach  BitVector RegMap(32);
170311e03e7c2d0c163e54b911ad1e665616dc0bcc8cJim Grosbach  for (unsigned i = 0, e = Registers.size(); i != e; ++i) {
170411e03e7c2d0c163e54b911ad1e665616dc0bcc8cJim Grosbach    const std::pair<unsigned, SMLoc> &RegInfo = Registers[i];
17057caebff83d90a59aa74876ff887e822387f479e0Bill Wendling    unsigned Reg = getARMRegisterNumbering(RegInfo.first);
1706e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
17078e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling    if (RegMap[Reg]) {
1708e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      Error(RegInfo.second, "register duplicated in register list");
170950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
1710e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    }
1711e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
17128e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling    if (!EmittedWarning && Reg < HighRegNum)
1713e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      Warning(RegInfo.second,
1714e717610f53e0465cde198536561a3c00ce29d59fBill Wendling              "register not in ascending order in register list");
1715e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
171611e03e7c2d0c163e54b911ad1e665616dc0bcc8cJim Grosbach    RegMap.set(Reg);
17178e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling    HighRegNum = std::max(Reg, HighRegNum);
1718e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  }
1719e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
172050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  Operands.push_back(ARMOperand::CreateRegList(Registers, S, E));
172150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  return false;
1722d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby}
1723d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
172443904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options.
1725f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
172643904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1727706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
1728706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
1729706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1730706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  StringRef OptStr = Tok.getString();
1731706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
1732706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size()))
1733706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("sy",    ARM_MB::SY)
1734706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("st",    ARM_MB::ST)
1735032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("sh",    ARM_MB::ISH)
1736706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("ish",   ARM_MB::ISH)
1737032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("shst",  ARM_MB::ISHST)
1738706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("ishst", ARM_MB::ISHST)
1739706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("nsh",   ARM_MB::NSH)
1740032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("un",    ARM_MB::NSH)
1741706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("nshst", ARM_MB::NSHST)
1742032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("unst",  ARM_MB::NSHST)
1743706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("osh",   ARM_MB::OSH)
1744706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("oshst", ARM_MB::OSHST)
1745706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Default(~0U);
1746706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
1747706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  if (Opt == ~0U)
1748f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
1749706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
1750706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
1751706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S));
1752f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
1753706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes}
1754706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
175543904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseProcIFlagsOperand - Try to parse iflags from CPS instruction.
1756a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
175743904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1758a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
1759a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
1760a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1761a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  StringRef IFlagsStr = Tok.getString();
1762a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1763a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  unsigned IFlags = 0;
1764a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  for (int i = 0, e = IFlagsStr.size(); i != e; ++i) {
1765a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1))
1766a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    .Case("a", ARM_PROC::A)
1767a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    .Case("i", ARM_PROC::I)
1768a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    .Case("f", ARM_PROC::F)
1769a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    .Default(~0U);
1770a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1771a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // If some specific iflag is already set, it means that some letter is
1772a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // present more than once, this is not acceptable.
1773a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    if (Flag == ~0U || (IFlags & Flag))
1774a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      return MatchOperand_NoMatch;
1775a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1776a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    IFlags |= Flag;
1777a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
1778a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1779a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
1780a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S));
1781a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  return MatchOperand_Success;
1782584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes}
1783584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
178443904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMSRMaskOperand - Try to parse mask flags from MSR instruction.
1785584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
178643904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1787584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
1788584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
1789584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1790584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  StringRef Mask = Tok.getString();
1791584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1792584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf"
1793584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  size_t Start = 0, Next = Mask.find('_');
1794584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  StringRef Flags = "";
1795b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach  std::string SpecReg = LowercaseString(Mask.slice(Start, Next));
1796584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (Next != StringRef::npos)
1797584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Flags = Mask.slice(Next+1, Mask.size());
1798584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1799584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // FlagsVal contains the complete mask:
1800584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // 3-0: Mask
1801584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // 4: Special Reg (cpsr, apsr => 0; spsr => 1)
1802584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  unsigned FlagsVal = 0;
1803584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1804584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (SpecReg == "apsr") {
1805584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal = StringSwitch<unsigned>(Flags)
1806b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach    .Case("nzcvq",  0x8) // same as CPSR_f
1807584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Case("g",      0x4) // same as CPSR_s
1808584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Case("nzcvqg", 0xc) // same as CPSR_fs
1809584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Default(~0U);
1810584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
18114b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger    if (FlagsVal == ~0U) {
1812584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      if (!Flags.empty())
1813584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        return MatchOperand_NoMatch;
1814584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      else
1815584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        FlagsVal = 0; // No flag
18164b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger    }
1817584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  } else if (SpecReg == "cpsr" || SpecReg == "spsr") {
181856926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes    if (Flags == "all") // cpsr_all is an alias for cpsr_fc
181956926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes      Flags = "fc";
1820584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    for (int i = 0, e = Flags.size(); i != e; ++i) {
1821584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1))
1822584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("c", 1)
1823584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("x", 2)
1824584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("s", 4)
1825584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("f", 8)
1826584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Default(~0U);
1827584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1828584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      // If some specific flag is already set, it means that some letter is
1829584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      // present more than once, this is not acceptable.
1830584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      if (FlagsVal == ~0U || (FlagsVal & Flag))
1831584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        return MatchOperand_NoMatch;
1832584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      FlagsVal |= Flag;
1833584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    }
1834584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  } else // No match for special register.
1835584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return MatchOperand_NoMatch;
1836584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1837584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Special register without flags are equivalent to "fc" flags.
1838584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (!FlagsVal)
1839584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal = 0x9;
1840584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1841584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1)
1842584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (SpecReg == "spsr")
1843584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal |= 16;
1844584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1845584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
1846584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
1847584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  return MatchOperand_Success;
1848a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes}
1849a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1850f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
1851f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachparsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands, StringRef Op,
1852f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach            int Low, int High) {
1853f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const AsmToken &Tok = Parser.getTok();
1854f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
1855f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), Op + " operand expected.");
1856f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
1857f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
1858f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  StringRef ShiftName = Tok.getString();
1859f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  std::string LowerOp = LowercaseString(Op);
1860f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  std::string UpperOp = UppercaseString(Op);
1861f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (ShiftName != LowerOp && ShiftName != UpperOp) {
1862f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), Op + " operand expected.");
1863f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
1864f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
1865f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Parser.Lex(); // Eat shift type token.
1866f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
1867f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  // There must be a '#' and a shift amount.
1868f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash)) {
1869f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
1870f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
1871f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
1872f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Parser.Lex(); // Eat hash token.
1873f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
1874f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const MCExpr *ShiftAmount;
1875f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  SMLoc Loc = Parser.getTok().getLoc();
1876f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (getParser().ParseExpression(ShiftAmount)) {
1877f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "illegal expression");
1878f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
1879f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
1880f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
1881f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (!CE) {
1882f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "constant expression expected");
1883f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
1884f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
1885f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  int Val = CE->getValue();
1886f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (Val < Low || Val > High) {
1887f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "immediate value out of range");
1888f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
1889f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
1890f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
1891f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Operands.push_back(ARMOperand::CreateImm(CE, Loc, Parser.getTok().getLoc()));
1892f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
1893f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  return MatchOperand_Success;
1894f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach}
1895f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
1896c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
1897c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachparseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1898c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  const AsmToken &Tok = Parser.getTok();
1899c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  SMLoc S = Tok.getLoc();
1900c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
1901c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Error(Tok.getLoc(), "'be' or 'le' operand expected");
1902c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return MatchOperand_ParseFail;
1903c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
1904c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  int Val = StringSwitch<int>(Tok.getString())
1905c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Case("be", 1)
1906c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Case("le", 0)
1907c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Default(-1);
1908c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  Parser.Lex(); // Eat the token.
1909c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach
1910c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (Val == -1) {
1911c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Error(Tok.getLoc(), "'be' or 'le' operand expected");
1912c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return MatchOperand_ParseFail;
1913c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
1914c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::Create(Val,
1915c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                                                                  getContext()),
1916c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                                           S, Parser.getTok().getLoc()));
1917c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  return MatchOperand_Success;
1918c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach}
1919c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach
1920580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// parseShifterImm - Parse the shifter immediate operand for SSAT/USAT
1921580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// instructions. Legal values are:
1922580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach///     lsl #n  'n' in [0,31]
1923580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach///     asr #n  'n' in [1,32]
1924580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach///             n == 32 encoded as n == 0.
1925580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
1926580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachparseShifterImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1927580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  const AsmToken &Tok = Parser.getTok();
1928580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  SMLoc S = Tok.getLoc();
1929580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
1930580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(S, "shift operator 'asr' or 'lsl' expected");
1931580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
1932580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
1933580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  StringRef ShiftName = Tok.getString();
1934580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  bool isASR;
1935580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (ShiftName == "lsl" || ShiftName == "LSL")
1936580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    isASR = false;
1937580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  else if (ShiftName == "asr" || ShiftName == "ASR")
1938580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    isASR = true;
1939580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  else {
1940580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(S, "shift operator 'asr' or 'lsl' expected");
1941580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
1942580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
1943580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  Parser.Lex(); // Eat the operator.
1944580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
1945580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  // A '#' and a shift amount.
1946580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash)) {
1947580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
1948580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
1949580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
1950580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  Parser.Lex(); // Eat hash token.
1951580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
1952580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  const MCExpr *ShiftAmount;
1953580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  SMLoc E = Parser.getTok().getLoc();
1954580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (getParser().ParseExpression(ShiftAmount)) {
1955580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(E, "malformed shift expression");
1956580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
1957580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
1958580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
1959580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (!CE) {
1960580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(E, "shift amount must be an immediate");
1961580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
1962580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
1963580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
1964580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  int64_t Val = CE->getValue();
1965580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (isASR) {
1966580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    // Shift amount must be in [1,32]
1967580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    if (Val < 1 || Val > 32) {
1968580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      Error(E, "'asr' shift amount must be in range [1,32]");
1969580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      return MatchOperand_ParseFail;
1970580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    }
1971580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    // asr #32 encoded as asr #0.
1972580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    if (Val == 32) Val = 0;
1973580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  } else {
1974580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    // Shift amount must be in [1,32]
1975580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    if (Val < 0 || Val > 31) {
1976580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      Error(E, "'lsr' shift amount must be in range [0,31]");
1977580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      return MatchOperand_ParseFail;
1978580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    }
1979580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
1980580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
1981580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  E = Parser.getTok().getLoc();
1982580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  Operands.push_back(ARMOperand::CreateShifterImm(isASR, Val, S, E));
1983580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
1984580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  return MatchOperand_Success;
1985580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach}
1986580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
19877e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// parseRotImm - Parse the shifter immediate operand for SXTB/UXTB family
19887e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// of instructions. Legal values are:
19897e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach///     ror #n  'n' in {0, 8, 16, 24}
19907e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
19917e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachparseRotImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
19927e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  const AsmToken &Tok = Parser.getTok();
19937e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  SMLoc S = Tok.getLoc();
19947e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
19957e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(S, "rotate operator 'ror' expected");
19967e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
19977e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
19987e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  StringRef ShiftName = Tok.getString();
19997e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (ShiftName != "ror" && ShiftName != "ROR") {
20007e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(S, "rotate operator 'ror' expected");
20017e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
20027e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
20037e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  Parser.Lex(); // Eat the operator.
20047e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
20057e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // A '#' and a rotate amount.
20067e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash)) {
20077e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
20087e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
20097e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
20107e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  Parser.Lex(); // Eat hash token.
20117e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
20127e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  const MCExpr *ShiftAmount;
20137e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
20147e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (getParser().ParseExpression(ShiftAmount)) {
20157e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(E, "malformed rotate expression");
20167e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
20177e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
20187e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
20197e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (!CE) {
20207e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(E, "rotate amount must be an immediate");
20217e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
20227e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
20237e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
20247e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  int64_t Val = CE->getValue();
20257e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // Shift amount must be in {0, 8, 16, 24} (0 is undocumented extension)
20267e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // normally, zero is represented in asm by omitting the rotate operand
20277e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // entirely.
20287e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (Val != 8 && Val != 16 && Val != 24 && Val != 0) {
20297e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(E, "'ror' rotate amount must be 8, 16, or 24");
20307e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
20317e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
20327e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
20337e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  E = Parser.getTok().getLoc();
20347e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  Operands.push_back(ARMOperand::CreateRotImm(Val, S, E));
20357e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
20367e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  return MatchOperand_Success;
20377e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach}
20387e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
2039293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
2040293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachparseBitfield(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2041293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  SMLoc S = Parser.getTok().getLoc();
2042293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // The bitfield descriptor is really two operands, the LSB and the width.
2043293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash)) {
2044293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
2045293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2046293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2047293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Parser.Lex(); // Eat hash token.
2048293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
2049293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  const MCExpr *LSBExpr;
2050293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
2051293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (getParser().ParseExpression(LSBExpr)) {
2052293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "malformed immediate expression");
2053293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2054293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2055293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LSBExpr);
2056293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (!CE) {
2057293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'lsb' operand must be an immediate");
2058293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2059293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2060293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
2061293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  int64_t LSB = CE->getValue();
2062293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // The LSB must be in the range [0,31]
2063293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (LSB < 0 || LSB > 31) {
2064293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'lsb' operand must be in the range [0,31]");
2065293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2066293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2067293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  E = Parser.getTok().getLoc();
2068293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
2069293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // Expect another immediate operand.
2070293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Comma)) {
2071293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(Parser.getTok().getLoc(), "too few operands");
2072293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2073293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2074293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Parser.Lex(); // Eat hash token.
2075293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash)) {
2076293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
2077293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2078293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2079293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Parser.Lex(); // Eat hash token.
2080293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
2081293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  const MCExpr *WidthExpr;
2082293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (getParser().ParseExpression(WidthExpr)) {
2083293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "malformed immediate expression");
2084293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2085293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2086293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  CE = dyn_cast<MCConstantExpr>(WidthExpr);
2087293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (!CE) {
2088293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'width' operand must be an immediate");
2089293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2090293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2091293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
2092293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  int64_t Width = CE->getValue();
2093293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // The LSB must be in the range [1,32-lsb]
2094293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (Width < 1 || Width > 32 - LSB) {
2095293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'width' operand must be in the range [1,32-lsb]");
2096293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2097293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2098293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  E = Parser.getTok().getLoc();
2099293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
2100293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, E));
2101293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
2102293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  return MatchOperand_Success;
2103293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach}
2104293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
21057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
21067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
21077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Check for a post-index addressing register operand. Specifically:
2108f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  // postidx_reg := '+' register {, shift}
2109f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  //              | '-' register {, shift}
2110f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  //              | register {, shift}
21117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
21127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // This method must return MatchOperand_NoMatch without consuming any tokens
21137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // in the case where there is no match, as other alternatives take other
21147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // parse methods.
21157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  AsmToken Tok = Parser.getTok();
21167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  SMLoc S = Tok.getLoc();
21177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool haveEaten = false;
211816578b50889329eb62774148091ba0f38b681a09Jim Grosbach  bool isAdd = true;
21197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  int Reg = -1;
21207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Tok.is(AsmToken::Plus)) {
21217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '+' token.
21227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    haveEaten = true;
21237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  } else if (Tok.is(AsmToken::Minus)) {
21247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '-' token.
212516578b50889329eb62774148091ba0f38b681a09Jim Grosbach    isAdd = false;
21267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    haveEaten = true;
21277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
21287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Identifier))
21297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Reg = tryParseRegister();
21307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Reg == -1) {
21317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!haveEaten)
21327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return MatchOperand_NoMatch;
21337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Error(Parser.getTok().getLoc(), "register expected");
21347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return MatchOperand_ParseFail;
21357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
21367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
21377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
2138f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  ARM_AM::ShiftOpc ShiftTy = ARM_AM::no_shift;
2139f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  unsigned ShiftImm = 0;
21400d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach  if (Parser.getTok().is(AsmToken::Comma)) {
21410d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach    Parser.Lex(); // Eat the ','.
21420d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach    if (parseMemRegOffsetShift(ShiftTy, ShiftImm))
21430d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach      return MatchOperand_ParseFail;
21440d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach  }
2145f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach
2146f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy,
2147f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                                  ShiftImm, S, E));
21487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
21497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  return MatchOperand_Success;
21507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
21517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
2152251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
2153251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachparseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2154251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // Check for a post-index addressing register operand. Specifically:
2155251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // am3offset := '+' register
2156251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | '-' register
2157251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | register
2158251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | # imm
2159251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | # + imm
2160251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | # - imm
2161251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
2162251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // This method must return MatchOperand_NoMatch without consuming any tokens
2163251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // in the case where there is no match, as other alternatives take other
2164251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // parse methods.
2165251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  AsmToken Tok = Parser.getTok();
2166251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  SMLoc S = Tok.getLoc();
2167251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
2168251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // Do immediates first, as we always parse those if we have a '#'.
2169251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  if (Parser.getTok().is(AsmToken::Hash)) {
2170251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Parser.Lex(); // Eat the '#'.
2171251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // Explicitly look for a '-', as we need to encode negative zero
2172251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // differently.
2173251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    bool isNegative = Parser.getTok().is(AsmToken::Minus);
2174251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    const MCExpr *Offset;
2175251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (getParser().ParseExpression(Offset))
2176251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return MatchOperand_ParseFail;
2177251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset);
2178251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (!CE) {
2179251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      Error(S, "constant expression expected");
2180251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return MatchOperand_ParseFail;
2181251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    }
2182251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    SMLoc E = Tok.getLoc();
2183251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // Negative zero is encoded as the flag value INT32_MIN.
2184251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    int32_t Val = CE->getValue();
2185251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (isNegative && Val == 0)
2186251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      Val = INT32_MIN;
2187251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
2188251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Operands.push_back(
2189251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      ARMOperand::CreateImm(MCConstantExpr::Create(Val, getContext()), S, E));
2190251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
2191251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    return MatchOperand_Success;
2192251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  }
2193251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
2194251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
2195251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  bool haveEaten = false;
2196251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  bool isAdd = true;
2197251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  int Reg = -1;
2198251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  if (Tok.is(AsmToken::Plus)) {
2199251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Parser.Lex(); // Eat the '+' token.
2200251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    haveEaten = true;
2201251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  } else if (Tok.is(AsmToken::Minus)) {
2202251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Parser.Lex(); // Eat the '-' token.
2203251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    isAdd = false;
2204251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    haveEaten = true;
2205251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  }
2206251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  if (Parser.getTok().is(AsmToken::Identifier))
2207251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Reg = tryParseRegister();
2208251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  if (Reg == -1) {
2209251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (!haveEaten)
2210251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return MatchOperand_NoMatch;
2211251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Error(Parser.getTok().getLoc(), "register expected");
2212251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    return MatchOperand_ParseFail;
2213251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  }
2214251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
2215251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
2216251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ARM_AM::no_shift,
2217251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach                                                  0, S, E));
2218251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
2219251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  return MatchOperand_Success;
2220251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach}
2221251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
22221355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
2223ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2224ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
2225ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser::
22261355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
2227ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2228ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
2229ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
2230ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Create a writeback register dummy placeholder.
2231ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
2232ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
22337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3);
2234ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2235ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  return true;
2236ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
2237ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
22389ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// cvtLdWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst.
22399ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// Needed here because the Asm Gen Matcher can't handle properly tied operands
22409ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// when they refer multiple MIOperands inside a single one.
22419ab0f25fc194b4315db1b87d38d4024054120bf6Owen Andersonbool ARMAsmParser::
22429ab0f25fc194b4315db1b87d38d4024054120bf6Owen AndersoncvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
22439ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
22449ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
22459ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
22469ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  // Create a writeback register dummy placeholder.
22479ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  Inst.addOperand(MCOperand::CreateImm(0));
22489ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
22499ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2);
22509ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
22519ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  return true;
22529ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson}
22539ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
22549ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
2255548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// cvtStWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst.
2256548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2257548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// when they refer multiple MIOperands inside a single one.
2258548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbachbool ARMAsmParser::
2259548340c4bfa596b602f286dfd3a8782817859d95Jim GrosbachcvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
2260548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2261548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  // Create a writeback register dummy placeholder.
2262548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
2263548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
2264548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2);
2265548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2266548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  return true;
2267548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach}
2268548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach
22691355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
2270ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2271ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
2272ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser::
22731355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
2274ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2275ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Create a writeback register dummy placeholder.
2276ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
2277548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
2278548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3);
2279548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
22807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  return true;
22817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
22827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
22837b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// cvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
22847b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
22857b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// when they refer multiple MIOperands inside a single one.
22867b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbachbool ARMAsmParser::
22877b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim GrosbachcvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
22887b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
22897b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  // Create a writeback register dummy placeholder.
22907b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
22917b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
22927b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3);
22937b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
22947b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  return true;
22957b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach}
22967b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach
22977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackImm - Convert parsed operands to MCInst.
22987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
22997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one.
23007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::
23017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
23027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
23037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
2304ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
23057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Create a writeback register dummy placeholder.
23067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
23077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
23087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
23097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
23107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1);
23117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
2312ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2313ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  return true;
2314ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
2315ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
23167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackReg - Convert parsed operands to MCInst.
2317ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2318ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
2319ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser::
23207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
23217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
23227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
2323aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
2324ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  // Create a writeback register dummy placeholder.
2325ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
23267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
23277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
23287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
23297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2);
23307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
23317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
23327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  return true;
23337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
2334aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson
23357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackImm - Convert parsed operands to MCInst.
23367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
23377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one.
23387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::
23397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
23407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
23417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Create a writeback register dummy placeholder.
23427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
23437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
23447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
23457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
23467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
23477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
23487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1);
23497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
2350ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2351ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  return true;
2352ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
2353ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
23547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackReg - Convert parsed operands to MCInst.
2355ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2356ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
2357ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser::
23587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
23597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2360ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  // Create a writeback register dummy placeholder.
2361ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
23627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
2363ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
23647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
23657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
23667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
23677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2);
23687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
2369ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2370ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  return true;
2371ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
2372ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
23732fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// cvtLdrdPre - Convert parsed operands to MCInst.
23742fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
23752fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// when they refer multiple MIOperands inside a single one.
23762fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbachbool ARMAsmParser::
23772fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim GrosbachcvtLdrdPre(MCInst &Inst, unsigned Opcode,
23782fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach           const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
23792fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // Rt, Rt2
23802fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
23812fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
23822fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // Create a writeback register dummy placeholder.
23832fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
23842fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // addr
23852fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3);
23862fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // pred
23872fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
23882fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  return true;
23892fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach}
23902fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
239114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// cvtStrdPre - Convert parsed operands to MCInst.
239214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
239314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// when they refer multiple MIOperands inside a single one.
239414605d1a679d55ff25875656e100ff455194ee17Jim Grosbachbool ARMAsmParser::
239514605d1a679d55ff25875656e100ff455194ee17Jim GrosbachcvtStrdPre(MCInst &Inst, unsigned Opcode,
239614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach           const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
239714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // Create a writeback register dummy placeholder.
239814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
239914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // Rt, Rt2
240014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
240114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
240214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // addr
240314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3);
240414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // pred
240514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
240614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  return true;
240714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach}
240814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach
2409623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// cvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
2410623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2411623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// when they refer multiple MIOperands inside a single one.
2412623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbachbool ARMAsmParser::
2413623a454b0f5c300e69a19984d7855a1e976c3d09Jim GrosbachcvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
2414623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2415623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
2416623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  // Create a writeback register dummy placeholder.
2417623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
2418623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3);
2419623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2420623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  return true;
2421623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach}
2422623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach
242388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// cvtThumbMultiple- Convert parsed operands to MCInst.
242488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
242588ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// when they refer multiple MIOperands inside a single one.
242688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbachbool ARMAsmParser::
242788ae2bc6d53bbf58422ff74729da18a53e155b4aJim GrosbachcvtThumbMultiply(MCInst &Inst, unsigned Opcode,
242888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach           const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
242988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  // The second source operand must be the same register as the destination
243088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  // operand.
243188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  if (Operands.size() == 6 &&
24327a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach      (((ARMOperand*)Operands[3])->getReg() !=
24337a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach       ((ARMOperand*)Operands[5])->getReg()) &&
24347a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach      (((ARMOperand*)Operands[3])->getReg() !=
24357a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach       ((ARMOperand*)Operands[4])->getReg())) {
243688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    Error(Operands[3]->getStartLoc(),
24377a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach          "destination register must match source register");
243888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    return false;
243988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  }
244088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
244188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  ((ARMOperand*)Operands[1])->addCCOutOperands(Inst, 1);
244288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  ((ARMOperand*)Operands[4])->addRegOperands(Inst, 1);
24437a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach  // If we have a three-operand form, use that, else the second source operand
24447a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach  // is just the destination operand again.
24457a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach  if (Operands.size() == 6)
24467a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach    ((ARMOperand*)Operands[5])->addRegOperands(Inst, 1);
24477a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach  else
24487a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach    Inst.addOperand(Inst.getOperand(0));
244988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  ((ARMOperand*)Operands[2])->addCondCodeOperands(Inst, 2);
245088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach
245188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  return true;
245288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach}
2453623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach
2454e717610f53e0465cde198536561a3c00ce29d59fBill Wendling/// Parse an ARM memory expression, return false if successful else return true
24559c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error.  The first token must be a '[' when called.
245650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
24577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2458762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
245918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  assert(Parser.getTok().is(AsmToken::LBrac) &&
2460a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling         "Token is not a Left Bracket");
2461762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  S = Parser.getTok().getLoc();
2462b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat left bracket token.
2463a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
246418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &BaseRegTok = Parser.getTok();
24651355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  int BaseRegNum = tryParseRegister();
24667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (BaseRegNum == -1)
24677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(BaseRegTok.getLoc(), "register expected");
2468a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
24690571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  // The next token must either be a comma or a closing bracket.
24700571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  const AsmToken &Tok = Parser.getTok();
24710571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac))
24727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(Tok.getLoc(), "malformed memory operand");
24730571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar
24747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Tok.is(AsmToken::RBrac)) {
2475762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = Tok.getLoc();
2476b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat right bracket token.
2477a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
24787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0, ARM_AM::no_shift,
24797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                             0, false, S, E));
248003f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach
24817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return false;
24827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
248350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
24847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  assert(Tok.is(AsmToken::Comma) && "Lost comma in memory operand?!");
24857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Parser.Lex(); // Eat the comma.
248650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
24877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // If we have a '#' it's an immediate offset, else assume it's a register
24887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset.
24897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Hash)) {
24907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '#'.
24917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    E = Parser.getTok().getLoc();
249250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
24937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // FIXME: Special case #-0 so we can correctly set the U bit.
2494e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby
24957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCExpr *Offset;
24967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (getParser().ParseExpression(Offset))
24977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach     return true;
249805d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
24997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // The expression has to be a constant. Memory references with relocations
25007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // don't come through here, as they use the <label> forms of the relevant
25017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // instructions.
25027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset);
25037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!CE)
25047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error (E, "constant expression expected");
25057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
25067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Now we should have the closing ']'
25077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    E = Parser.getTok().getLoc();
25087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Parser.getTok().isNot(AsmToken::RBrac))
25097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(E, "']' expected");
25107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat right bracket token.
251105d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
25127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Don't worry about range checking the value here. That's handled by
25137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // the is*() predicates.
25147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Operands.push_back(ARMOperand::CreateMem(BaseRegNum, CE, 0,
25157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                             ARM_AM::no_shift, 0, false, S,E));
2516a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
25177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // If there's a pre-indexing writeback marker, '!', just add it as a token
25187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // operand.
25197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Parser.getTok().is(AsmToken::Exclaim)) {
25207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
25217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Parser.Lex(); // Eat the '!'.
2522762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    }
25237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
25247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return false;
25259c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
2526d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
25277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // The register offset is optionally preceded by a '+' or '-'
25287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isNegative = false;
25297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Minus)) {
25307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    isNegative = true;
25317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '-'.
25327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  } else if (Parser.getTok().is(AsmToken::Plus)) {
25337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Nothing to do.
25347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '+'.
25357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
25369c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
25377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  E = Parser.getTok().getLoc();
25387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  int OffsetRegNum = tryParseRegister();
25397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (OffsetRegNum == -1)
25407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(E, "register expected");
25417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
25427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // If there's a shift operator, handle it.
25437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ARM_AM::ShiftOpc ShiftType = ARM_AM::no_shift;
25440d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach  unsigned ShiftImm = 0;
25457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Comma)) {
25467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the ','.
25470d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach    if (parseMemRegOffsetShift(ShiftType, ShiftImm))
25487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return true;
25499c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
255016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
25517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Now we should have the closing ']'
25527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  E = Parser.getTok().getLoc();
25537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().isNot(AsmToken::RBrac))
25547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(E, "']' expected");
25557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Parser.Lex(); // Eat right bracket token.
25567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
25577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, OffsetRegNum,
25580d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach                                           ShiftType, ShiftImm, isNegative,
25597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                           S, E));
25607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
2561f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  // If there's a pre-indexing writeback marker, '!', just add it as a token
2562f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  // operand.
2563f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  if (Parser.getTok().is(AsmToken::Exclaim)) {
2564f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
2565f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Parser.Lex(); // Eat the '!'.
2566f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  }
25679c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
25689c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  return false;
25699c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby}
25709c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
25717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// parseMemRegOffsetShift - one of these two:
2572a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby///   ( lsl | lsr | asr | ror ) , # shift_amount
2573a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby///   rrx
25747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// return true if it parses a shift otherwise it returns false.
25757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::parseMemRegOffsetShift(ARM_AM::ShiftOpc &St,
25767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                          unsigned &Amount) {
25777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  SMLoc Loc = Parser.getTok().getLoc();
257818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
2579a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (Tok.isNot(AsmToken::Identifier))
2580a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return true;
258138e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  StringRef ShiftName = Tok.getString();
2582a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (ShiftName == "lsl" || ShiftName == "LSL")
25830082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::lsl;
2584a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "lsr" || ShiftName == "LSR")
25850082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::lsr;
2586a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "asr" || ShiftName == "ASR")
25870082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::asr;
2588a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "ror" || ShiftName == "ROR")
25890082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::ror;
2590a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "rrx" || ShiftName == "RRX")
25910082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::rrx;
2592a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else
25937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(Loc, "illegal shift operator");
2594b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat shift type token.
2595a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
25967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // rrx stands alone.
25977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Amount = 0;
25987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (St != ARM_AM::rrx) {
25997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Loc = Parser.getTok().getLoc();
26007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // A '#' and a shift amount.
26017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const AsmToken &HashTok = Parser.getTok();
26027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (HashTok.isNot(AsmToken::Hash))
26037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(HashTok.getLoc(), "'#' expected");
26047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat hash token.
26059c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
26067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCExpr *Expr;
26077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (getParser().ParseExpression(Expr))
26087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return true;
26097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Range check the immediate.
26107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // lsl, ror: 0 <= imm <= 31
26117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // lsr, asr: 0 <= imm <= 32
26127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
26137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!CE)
26147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(Loc, "shift amount must be an immediate");
26157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Imm = CE->getValue();
26167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Imm < 0 ||
26177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach        ((St == ARM_AM::lsl || St == ARM_AM::ror) && Imm > 31) ||
26187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach        ((St == ARM_AM::lsr || St == ARM_AM::asr) && Imm > 32))
26197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(Loc, "immediate shift value out of range");
26207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Amount = Imm;
26217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
2622a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2623a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  return false;
2624a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
2625a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
26269c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand.  For now this parses the operand regardless
26279c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic.
26281355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
2629fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes                                StringRef Mnemonic) {
2630762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
2631fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
2632fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  // Check if the current operand has a custom associated parser, if so, try to
2633fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  // custom parse the operand, or fallback to the general approach.
2634f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2635f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  if (ResTy == MatchOperand_Success)
2636fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return false;
2637f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // If there wasn't a custom match, try the generic matcher below. Otherwise,
2638f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // there was a match, but an error occurred, in which case, just return that
2639f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // the operand parsing failed.
2640f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  if (ResTy == MatchOperand_ParseFail)
2641f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return true;
2642fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
2643a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  switch (getLexer().getKind()) {
2644146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  default:
2645146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling    Error(Parser.getTok().getLoc(), "unexpected token in operand");
264650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
264719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  case AsmToken::Identifier: {
26481355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    if (!tryParseRegisterWithWriteBack(Operands))
264950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return false;
26500d87ec21d79c8622733b8367aa41067169602480Jim Grosbach    int Res = tryParseShiftRegister(Operands);
265119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    if (Res == 0) // success
26520082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      return false;
265319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    else if (Res == -1) // irrecoverable error
265419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      return true;
2655e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
2656e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    // Fall though for the Identifier case that is not a register or a
2657e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    // special name.
265819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  }
265967b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby  case AsmToken::Integer: // things like 1f and 2b as a branch targets
266067b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby  case AsmToken::Dot: {   // . as a branch target
2661515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    // This was not a register so parse other operands that start with an
2662515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    // identifier (like labels) as expressions and create them as immediates.
2663515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    const MCExpr *IdVal;
2664762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    S = Parser.getTok().getLoc();
2665515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    if (getParser().ParseExpression(IdVal))
266650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
2667762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
266850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateImm(IdVal, S, E));
266950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return false;
267050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  }
2671a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  case AsmToken::LBrac:
26721355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseMemory(Operands);
2673d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  case AsmToken::LCurly:
26741355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseRegisterList(Operands);
2675d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  case AsmToken::Hash:
2676079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby    // #42 -> immediate.
2677079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby    // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate
2678762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    S = Parser.getTok().getLoc();
2679b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
2680515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    const MCExpr *ImmVal;
2681515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    if (getParser().ParseExpression(ImmVal))
268250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
2683762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
268450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E));
268550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return false;
26869081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case AsmToken::Colon: {
26879081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    // ":lower16:" and ":upper16:" expression prefixes
26887597212abced110723f2fee985a7d60557c092ecEvan Cheng    // FIXME: Check it's an expression prefix,
26897597212abced110723f2fee985a7d60557c092ecEvan Cheng    // e.g. (FOO - :lower16:BAR) isn't legal.
26907597212abced110723f2fee985a7d60557c092ecEvan Cheng    ARMMCExpr::VariantKind RefKind;
26911355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    if (parsePrefix(RefKind))
26929081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return true;
26939081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
26947597212abced110723f2fee985a7d60557c092ecEvan Cheng    const MCExpr *SubExprVal;
26957597212abced110723f2fee985a7d60557c092ecEvan Cheng    if (getParser().ParseExpression(SubExprVal))
26969081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return true;
26979081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
26987597212abced110723f2fee985a7d60557c092ecEvan Cheng    const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal,
26997597212abced110723f2fee985a7d60557c092ecEvan Cheng                                                   getContext());
27009081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
27017597212abced110723f2fee985a7d60557c092ecEvan Cheng    Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E));
27029081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return false;
27039081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
2704a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
2705a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
2706a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
27071355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach// parsePrefix - Parse ARM 16-bit relocations expression prefix, i.e.
27087597212abced110723f2fee985a7d60557c092ecEvan Cheng//  :lower16: and :upper16:.
27091355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parsePrefix(ARMMCExpr::VariantKind &RefKind) {
27107597212abced110723f2fee985a7d60557c092ecEvan Cheng  RefKind = ARMMCExpr::VK_ARM_None;
27119081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
27129081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  // :lower16: and :upper16: modifiers
27138a8696db6b6f6e735bb9de630876af83946b45f9Jason W Kim  assert(getLexer().is(AsmToken::Colon) && "expected a :");
27149081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex(); // Eat ':'
27159081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
27169081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (getLexer().isNot(AsmToken::Identifier)) {
27179081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "expected prefix identifier in operand");
27189081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
27199081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
27209081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
27219081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  StringRef IDVal = Parser.getTok().getIdentifier();
27229081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (IDVal == "lower16") {
27237597212abced110723f2fee985a7d60557c092ecEvan Cheng    RefKind = ARMMCExpr::VK_ARM_LO16;
27249081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  } else if (IDVal == "upper16") {
27257597212abced110723f2fee985a7d60557c092ecEvan Cheng    RefKind = ARMMCExpr::VK_ARM_HI16;
27269081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  } else {
27279081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "unexpected prefix in operand");
27289081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
27299081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
27309081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex();
27319081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
27329081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (getLexer().isNot(AsmToken::Colon)) {
27339081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "unexpected token after prefix");
27349081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
27359081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
27369081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex(); // Eat the last ':'
27379081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  return false;
27389081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim}
27399081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
27409081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kimconst MCExpr *
27411355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachARMAsmParser::applyPrefixToExpr(const MCExpr *E,
27429081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim                                MCSymbolRefExpr::VariantKind Variant) {
27439081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  // Recurse over the given expression, rebuilding it to apply the given variant
27449081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  // to the leftmost symbol.
27459081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (Variant == MCSymbolRefExpr::VK_None)
27469081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return E;
27479081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
27489081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  switch (E->getKind()) {
27499081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::Target:
27509081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    llvm_unreachable("Can't handle target expr yet");
27519081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::Constant:
27529081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    llvm_unreachable("Can't handle lower16/upper16 of constant yet");
27539081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
27549081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::SymbolRef: {
27559081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
27569081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
27579081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    if (SRE->getKind() != MCSymbolRefExpr::VK_None)
27589081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return 0;
27599081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
27609081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return MCSymbolRefExpr::Create(&SRE->getSymbol(), Variant, getContext());
27619081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
27629081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
27639081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::Unary:
27649081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    llvm_unreachable("Can't handle unary expressions yet");
27659081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
27669081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::Binary: {
27679081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
27681355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    const MCExpr *LHS = applyPrefixToExpr(BE->getLHS(), Variant);
27699081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    const MCExpr *RHS = BE->getRHS();
27709081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    if (!LHS)
27719081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return 0;
27729081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
27739081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return MCBinaryExpr::Create(BE->getOpcode(), LHS, RHS, getContext());
27749081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
27759081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
27769081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
27779081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  assert(0 && "Invalid expression kind!");
27789081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  return 0;
27799081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim}
27809081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
2781352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// \brief Given a mnemonic, split out possible predication code and carry
2782352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// setting letters to form a canonical mnemonic and flags.
2783352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar//
2784badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar// FIXME: Would be nice to autogen this.
27851355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachStringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic,
27865f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach                                      unsigned &PredicationCode,
27875f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach                                      bool &CarrySetting,
27885f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach                                      unsigned &ProcessorIMod) {
2789352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  PredicationCode = ARMCC::AL;
2790352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  CarrySetting = false;
2791a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  ProcessorIMod = 0;
2792352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar
2793badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  // Ignore some mnemonics we know aren't predicated forms.
2794352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  //
2795352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // FIXME: Would be nice to autogen this.
27965f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach  if ((Mnemonic == "movs" && isThumb()) ||
27975f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "teq"   || Mnemonic == "vceq"   || Mnemonic == "svc"   ||
27985f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "mls"   || Mnemonic == "smmls"  || Mnemonic == "vcls"  ||
27995f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vmls"  || Mnemonic == "vnmls"  || Mnemonic == "vacge" ||
28005f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vcge"  || Mnemonic == "vclt"   || Mnemonic == "vacgt" ||
28015f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vcgt"  || Mnemonic == "vcle"   || Mnemonic == "smlal" ||
28025f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "umaal" || Mnemonic == "umlal"  || Mnemonic == "vabal" ||
28035f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal")
2804352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    return Mnemonic;
2805badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
28063f00e317064560ad11168d22030416d853829f6eJim Grosbach  // First, split out any predication code. Ignore mnemonics we know aren't
28073f00e317064560ad11168d22030416d853829f6eJim Grosbach  // predicated but do have a carry-set and so weren't caught above.
2808ab40f4b737b0a87c4048a9ad2f0c02be735e3770Jim Grosbach  if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" &&
280971725a099e6d0cba24a63f9c9063f6efee3bf76eJim Grosbach      Mnemonic != "muls" && Mnemonic != "smlals" && Mnemonic != "smulls" &&
281004d55f1905748b0d66655e2332e1a232a3f665f4Jim Grosbach      Mnemonic != "umlals" && Mnemonic != "umulls" && Mnemonic != "lsls" &&
281104d55f1905748b0d66655e2332e1a232a3f665f4Jim Grosbach      Mnemonic != "sbcs") {
28123f00e317064560ad11168d22030416d853829f6eJim Grosbach    unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2))
28133f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("eq", ARMCC::EQ)
28143f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ne", ARMCC::NE)
28153f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("hs", ARMCC::HS)
28163f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("cs", ARMCC::HS)
28173f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("lo", ARMCC::LO)
28183f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("cc", ARMCC::LO)
28193f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("mi", ARMCC::MI)
28203f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("pl", ARMCC::PL)
28213f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("vs", ARMCC::VS)
28223f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("vc", ARMCC::VC)
28233f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("hi", ARMCC::HI)
28243f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ls", ARMCC::LS)
28253f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ge", ARMCC::GE)
28263f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("lt", ARMCC::LT)
28273f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("gt", ARMCC::GT)
28283f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("le", ARMCC::LE)
28293f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("al", ARMCC::AL)
28303f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Default(~0U);
28313f00e317064560ad11168d22030416d853829f6eJim Grosbach    if (CC != ~0U) {
28323f00e317064560ad11168d22030416d853829f6eJim Grosbach      Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2);
28333f00e317064560ad11168d22030416d853829f6eJim Grosbach      PredicationCode = CC;
28343f00e317064560ad11168d22030416d853829f6eJim Grosbach    }
283552925b60f1cd4cf810524ca05b00a207a926ab9fBill Wendling  }
2836345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
2837352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // Next, determine if we have a carry setting bit. We explicitly ignore all
2838352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // the instructions we know end in 's'.
2839352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  if (Mnemonic.endswith("s") &&
284000f5d982057574cf65a4a3f29548ff9fb0ecfbd0Jim Grosbach      !(Mnemonic == "cps" || Mnemonic == "mls" ||
28415f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "mrs" || Mnemonic == "smmls" || Mnemonic == "vabs" ||
28425f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vmrs" ||
28435f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "vnmls" || Mnemonic == "vqabs" || Mnemonic == "vrecps" ||
2844e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach        Mnemonic == "vrsqrts" || Mnemonic == "srs" ||
2845e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach        (Mnemonic == "movs" && isThumb()))) {
2846352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1);
2847352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    CarrySetting = true;
2848352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  }
2849352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar
2850a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // The "cps" instruction can have a interrupt mode operand which is glued into
2851a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // the mnemonic. Check if this is the case, split it and parse the imod op
2852a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  if (Mnemonic.startswith("cps")) {
2853a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // Split out any imod code.
2854a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned IMod =
2855a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2))
2856a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Case("ie", ARM_PROC::IE)
2857a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Case("id", ARM_PROC::ID)
2858a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Default(~0U);
2859a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    if (IMod != ~0U) {
2860a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2);
2861a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      ProcessorIMod = IMod;
2862a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    }
2863a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
2864a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
2865352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  return Mnemonic;
2866352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar}
28673771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
28683771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// \brief Given a canonical mnemonic, determine if the instruction ever allows
28693771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// inclusion of carry set or predication code operands.
28703771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar//
28713771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// FIXME: It would be nice to autogen this.
2872fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopesvoid ARMAsmParser::
28731355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachgetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
2874fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes                      bool &CanAcceptPredicationCode) {
2875eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" ||
2876eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" ||
2877eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "smull" || Mnemonic == "add" || Mnemonic == "adc" ||
2878eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" ||
2879be64b394317feb8d7bcb732bdfb35e0b286efd4cBruno Cardoso Lopes      Mnemonic == "umlal" || Mnemonic == "orr" || Mnemonic == "mvn" ||
2880eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" ||
2881eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "sbc" || Mnemonic == "mla" || Mnemonic == "umull" ||
28822c3f70e5d4b4f179f21ed1b2ba14674f9d65c9b0Jim Grosbach      Mnemonic == "eor" || Mnemonic == "smlal" || Mnemonic == "neg" ||
2883194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach      // FIXME: We need a better way. This really confused Thumb2
2884194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach      // parsing for 'mov'.
2885ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng      (Mnemonic == "mov" && !isThumbOne())) {
2886eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar    CanAcceptCarrySet = true;
2887eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  } else {
2888eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar    CanAcceptCarrySet = false;
2889eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  }
28903771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
2891eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" ||
2892eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" ||
2893eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" ||
2894eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" ||
28955f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "clrex" ||
2896c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach      Mnemonic == "setend" ||
28970780b6303b99441fef04340b7a083006484f4743Jim Grosbach      (Mnemonic == "nop" && isThumbOne()) ||
289848c693ff564c422153733424ab845106161430acJim Grosbach      ((Mnemonic == "pld" || Mnemonic == "pli") && !isThumb()) ||
2899e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach      ((Mnemonic.startswith("rfe") || Mnemonic.startswith("srs"))
2900e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach        && !isThumb()) ||
29015f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumb())) {
29023771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    CanAcceptPredicationCode = false;
29033771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  } else {
29043771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    CanAcceptPredicationCode = true;
29053771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  }
2906fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes
2907ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  if (isThumb())
2908fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes    if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" ||
290963b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach        Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp")
2910fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes      CanAcceptPredicationCode = false;
2911badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar}
2912badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
2913d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbachbool ARMAsmParser::shouldOmitCCOutOperand(StringRef Mnemonic,
2914d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2915d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach
2916d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // The 'mov' mnemonic is special. One variant has a cc_out operand, while
2917d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // another does not. Specifically, the MOVW instruction does not. So we
2918d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // special case it here and remove the defaulted (non-setting) cc_out
2919d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // operand if that's the instruction we're trying to match.
2920d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  //
2921d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // We do this as post-processing of the explicit operands rather than just
2922d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // conditionally adding the cc_out in the first place because we need
2923d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // to check the type of the parsed immediate operand.
2924d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  if (Mnemonic == "mov" && Operands.size() > 4 &&
2925d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach      !static_cast<ARMOperand*>(Operands[4])->isARMSOImm() &&
2926d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isImm0_65535Expr() &&
2927d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0)
2928d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach    return true;
29293912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach
29303912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach  // Register-register 'add' for thumb does not have a cc_out operand
29313912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach  // when there are only two register operands.
29323912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach  if (isThumb() && Mnemonic == "add" && Operands.size() == 5 &&
29333912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
29343912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
29353912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0)
29363912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach    return true;
293772f39f8436848885176943b0ba985a7171145423Jim Grosbach  // Register-register 'add' for thumb does not have a cc_out operand
293872f39f8436848885176943b0ba985a7171145423Jim Grosbach  // when it's an ADD Rdm, SP, {Rdm|#imm} instruction.
293972f39f8436848885176943b0ba985a7171145423Jim Grosbach  if (isThumb() && Mnemonic == "add" && Operands.size() == 6 &&
294072f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
294172f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
294272f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->getReg() == ARM::SP &&
294372f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0)
294472f39f8436848885176943b0ba985a7171145423Jim Grosbach    return true;
2945f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // Register-register 'add/sub' for thumb does not have a cc_out operand
2946f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // when it's an ADD/SUB SP, #imm. Be lenient on count since there's also
2947f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // the "add/sub SP, SP, #imm" version. If the follow-up operands aren't
2948f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // right, this will result in better diagnostics (which operand is off)
2949f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // anyway.
2950f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  if (isThumb() && (Mnemonic == "add" || Mnemonic == "sub") &&
2951f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach      (Operands.size() == 5 || Operands.size() == 6) &&
295272f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
295372f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->getReg() == ARM::SP &&
295472f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0)
295572f39f8436848885176943b0ba985a7171145423Jim Grosbach    return true;
29563912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach
2957d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  return false;
2958d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach}
2959d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach
2960badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar/// Parse an arm instruction mnemonic followed by its operands.
2961badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbarbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc,
2962badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2963badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  // Create the leading tokens for the mnemonic, split by '.' characters.
2964badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  size_t Start = 0, Next = Name.find('.');
2965ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  StringRef Mnemonic = Name.slice(Start, Next);
2966badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
2967352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // Split out the predication code and carry setting flag from the mnemonic.
2968352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  unsigned PredicationCode;
2969a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  unsigned ProcessorIMod;
2970352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  bool CarrySetting;
29711355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  Mnemonic = splitMnemonic(Mnemonic, PredicationCode, CarrySetting,
2972c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                           ProcessorIMod);
2973badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
29740c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach  // In Thumb1, only the branch (B) instruction can be predicated.
29750c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach  if (isThumbOne() && PredicationCode != ARMCC::AL && Mnemonic != "b") {
29760c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach    Parser.EatToEndOfStatement();
29770c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach    return Error(NameLoc, "conditional execution not supported in Thumb1");
29780c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach  }
29790c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach
2980ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc));
2981ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
2982ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // FIXME: This is all a pretty gross hack. We should automatically handle
2983ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // optional operands like this via tblgen.
29849717fa9f29696bca45ddfdf206b1c382c8b40b78Bill Wendling
29853771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Next, add the CCOut and ConditionCode operands, if needed.
29863771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  //
29873771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // For mnemonics which can ever incorporate a carry setting bit or predication
29883771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // code, our matching model involves us always generating CCOut and
29893771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // ConditionCode operands to match the mnemonic "as written" and then we let
29903771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // the matcher deal with finding the right instruction or generating an
29913771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // appropriate error.
29923771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  bool CanAcceptCarrySet, CanAcceptPredicationCode;
29931355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  getMnemonicAcceptInfo(Mnemonic, CanAcceptCarrySet, CanAcceptPredicationCode);
29943771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
299533c16a27370939de39679245c3dff72383c210bdJim Grosbach  // If we had a carry-set on an instruction that can't do that, issue an
299633c16a27370939de39679245c3dff72383c210bdJim Grosbach  // error.
299733c16a27370939de39679245c3dff72383c210bdJim Grosbach  if (!CanAcceptCarrySet && CarrySetting) {
299833c16a27370939de39679245c3dff72383c210bdJim Grosbach    Parser.EatToEndOfStatement();
2999ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    return Error(NameLoc, "instruction '" + Mnemonic +
300033c16a27370939de39679245c3dff72383c210bdJim Grosbach                 "' can not set flags, but 's' suffix specified");
300133c16a27370939de39679245c3dff72383c210bdJim Grosbach  }
3002c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  // If we had a predication code on an instruction that can't do that, issue an
3003c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  // error.
3004c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (!CanAcceptPredicationCode && PredicationCode != ARMCC::AL) {
3005c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Parser.EatToEndOfStatement();
3006c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return Error(NameLoc, "instruction '" + Mnemonic +
3007c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                 "' is not predicable, but condition code specified");
3008c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
300933c16a27370939de39679245c3dff72383c210bdJim Grosbach
30103771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Add the carry setting operand, if necessary.
30113771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  //
30123771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // FIXME: It would be awesome if we could somehow invent a location such that
30133771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // match errors on this operand would print a nice diagnostic about how the
30143771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // 's' character in the mnemonic resulted in a CCOut operand.
301533c16a27370939de39679245c3dff72383c210bdJim Grosbach  if (CanAcceptCarrySet)
30163771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0,
30173771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar                                               NameLoc));
30183771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
30193771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Add the predication code operand, if necessary.
30203771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  if (CanAcceptPredicationCode) {
30213771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    Operands.push_back(ARMOperand::CreateCondCode(
30223771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar                         ARMCC::CondCodes(PredicationCode), NameLoc));
3023badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  }
3024345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
3025a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // Add the processor imod operand, if necessary.
3026a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  if (ProcessorIMod) {
3027a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Operands.push_back(ARMOperand::CreateImm(
3028a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes          MCConstantExpr::Create(ProcessorIMod, getContext()),
3029a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes                                 NameLoc, NameLoc));
3030a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  } else {
3031a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // This mnemonic can't ever accept a imod, but the user wrote
3032a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // one (or misspelled another mnemonic).
3033a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
3034a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // FIXME: Issue a nice error.
3035a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
3036a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
3037345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  // Add the remaining tokens in the mnemonic.
30385747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  while (Next != StringRef::npos) {
30395747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Start = Next;
30405747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Next = Name.find('.', Start + 1);
3041a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    StringRef ExtraToken = Name.slice(Start, Next);
3042a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
30434d23e99d2a272a4de06ee31eee6d8e501809a573Jim Grosbach    // For now, we're only parsing Thumb1 (for the most part), so
30444d23e99d2a272a4de06ee31eee6d8e501809a573Jim Grosbach    // just ignore ".n" qualifiers. We'll use them to restrict
30454d23e99d2a272a4de06ee31eee6d8e501809a573Jim Grosbach    // matching when we do Thumb2.
30464d23e99d2a272a4de06ee31eee6d8e501809a573Jim Grosbach    if (ExtraToken != ".n")
30474d23e99d2a272a4de06ee31eee6d8e501809a573Jim Grosbach      Operands.push_back(ARMOperand::CreateToken(ExtraToken, NameLoc));
30485747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  }
30495747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar
30505747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  // Read the remaining operands.
30515747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  if (getLexer().isNot(AsmToken::EndOfStatement)) {
3052a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    // Read the first operand.
30531355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    if (parseOperand(Operands, Mnemonic)) {
3054cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      Parser.EatToEndOfStatement();
3055cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      return true;
3056cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    }
3057a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
3058a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    while (getLexer().is(AsmToken::Comma)) {
3059b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();  // Eat the comma.
3060a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
3061a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      // Parse and remember the operand.
30621355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach      if (parseOperand(Operands, Mnemonic)) {
3063cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        Parser.EatToEndOfStatement();
3064cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        return true;
3065cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      }
3066a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    }
3067a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
306816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
3069cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner  if (getLexer().isNot(AsmToken::EndOfStatement)) {
3070cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    Parser.EatToEndOfStatement();
307134e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner    return TokError("unexpected token in argument list");
3072cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner  }
3073146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling
307434e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner  Parser.Lex(); // Consume the EndOfStatement
3075ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
3076d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // Some instructions, mostly Thumb, have forms for the same mnemonic that
3077d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // do and don't have a cc_out optional-def operand. With some spot-checks
3078d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // of the operand list, we can figure out which variant we're trying to
3079d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // parse and adjust accordingly before actually matching. Reason number
3080d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // #317 the table driven matcher doesn't fit well with the ARM instruction
3081d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // set.
3082d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  if (shouldOmitCCOutOperand(Mnemonic, Operands)) {
3083ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]);
3084ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    Operands.erase(Operands.begin() + 1);
3085ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    delete Op;
3086ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
3087ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
3088cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // ARM mode 'blx' need special handling, as the register operand version
3089cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // is predicable, but the label operand version is not. So, we can't rely
3090cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // on the Mnemonic based checking to correctly figure out when to put
3091cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // a CondCode operand in the list. If we're trying to match the label
3092cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // version, remove the CondCode operand here.
3093cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  if (!isThumb() && Mnemonic == "blx" && Operands.size() == 3 &&
3094cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach      static_cast<ARMOperand*>(Operands[2])->isImm()) {
3095cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]);
3096cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach    Operands.erase(Operands.begin() + 1);
3097cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach    delete Op;
3098cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  }
3099857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach
3100857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  // The vector-compare-to-zero instructions have a literal token "#0" at
3101857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  // the end that comes to here as an immediate operand. Convert it to a
3102857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  // token to play nicely with the matcher.
3103857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  if ((Mnemonic == "vceq" || Mnemonic == "vcge" || Mnemonic == "vcgt" ||
3104857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      Mnemonic == "vcle" || Mnemonic == "vclt") && Operands.size() == 6 &&
3105857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      static_cast<ARMOperand*>(Operands[5])->isImm()) {
3106857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]);
3107857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
3108857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    if (CE && CE->getValue() == 0) {
3109857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      Operands.erase(Operands.begin() + 5);
3110857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc()));
3111857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      delete Op;
3112857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    }
3113857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  }
3114934755ac040c516eac7fdd974e87590543acd16aJim Grosbach  // Similarly, the Thumb1 "RSB" instruction has a literal "#0" on the
3115934755ac040c516eac7fdd974e87590543acd16aJim Grosbach  // end. Convert it to a token here.
3116934755ac040c516eac7fdd974e87590543acd16aJim Grosbach  if (Mnemonic == "rsb" && isThumb() && Operands.size() == 6 &&
3117934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      static_cast<ARMOperand*>(Operands[5])->isImm()) {
3118934755ac040c516eac7fdd974e87590543acd16aJim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]);
3119934755ac040c516eac7fdd974e87590543acd16aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
3120934755ac040c516eac7fdd974e87590543acd16aJim Grosbach    if (CE && CE->getValue() == 0) {
3121934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      Operands.erase(Operands.begin() + 5);
3122934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc()));
3123934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      delete Op;
3124934755ac040c516eac7fdd974e87590543acd16aJim Grosbach    }
3125934755ac040c516eac7fdd974e87590543acd16aJim Grosbach  }
3126934755ac040c516eac7fdd974e87590543acd16aJim Grosbach
31279898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner  return false;
3128ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
3129ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
3130189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// Validate context-sensitive operand constraints.
3131aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach
3132aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// return 'true' if register list contains non-low GPR registers,
3133aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'false' otherwise. If Reg is in the register list or is HiReg, set
3134aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'containsReg' to true.
3135aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbachstatic bool checkLowRegisterList(MCInst Inst, unsigned OpNo, unsigned Reg,
3136aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                                 unsigned HiReg, bool &containsReg) {
3137aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  containsReg = false;
3138aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) {
3139aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    unsigned OpReg = Inst.getOperand(i).getReg();
3140aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (OpReg == Reg)
3141aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      containsReg = true;
3142aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    // Anything other than a low register isn't legal here.
3143aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (!isARMLowRegister(OpReg) && (!HiReg || OpReg != HiReg))
3144aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return true;
3145aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  }
3146aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  return false;
3147aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach}
3148aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach
3149189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// FIXME: We would really like to be able to tablegen'erate this.
3150189610f9466686a91fb7d847b572e1645c785323Jim Grosbachbool ARMAsmParser::
3151189610f9466686a91fb7d847b572e1645c785323Jim GrosbachvalidateInstruction(MCInst &Inst,
3152189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                    const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3153189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  switch (Inst.getOpcode()) {
31542fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  case ARM::LDRD:
31552fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  case ARM::LDRD_PRE:
31562fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  case ARM::LDRD_POST:
3157189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  case ARM::LDREXD: {
3158189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // Rt2 must be Rt + 1.
3159189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg());
3160189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg());
3161189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    if (Rt2 != Rt + 1)
3162189610f9466686a91fb7d847b572e1645c785323Jim Grosbach      return Error(Operands[3]->getStartLoc(),
3163189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                   "destination operands must be sequential");
3164189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    return false;
3165189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  }
316614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  case ARM::STRD: {
316714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    // Rt2 must be Rt + 1.
316814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg());
316914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg());
317014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    if (Rt2 != Rt + 1)
317114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach      return Error(Operands[3]->getStartLoc(),
317214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach                   "source operands must be sequential");
317314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    return false;
317414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  }
317553642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach  case ARM::STRD_PRE:
317653642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach  case ARM::STRD_POST:
3177189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  case ARM::STREXD: {
3178189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // Rt2 must be Rt + 1.
3179189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt = getARMRegisterNumbering(Inst.getOperand(1).getReg());
3180189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(2).getReg());
3181189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    if (Rt2 != Rt + 1)
318214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach      return Error(Operands[3]->getStartLoc(),
3183189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                   "source operands must be sequential");
3184189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    return false;
3185189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  }
3186fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach  case ARM::SBFX:
3187fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach  case ARM::UBFX: {
3188fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    // width must be in range [1, 32-lsb]
3189fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    unsigned lsb = Inst.getOperand(2).getImm();
3190fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    unsigned widthm1 = Inst.getOperand(3).getImm();
3191fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    if (widthm1 >= 32 - lsb)
3192fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach      return Error(Operands[5]->getStartLoc(),
3193fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach                   "bitfield width must be in range [1,32-lsb]");
319400c9a518886c4f2d1cd869c174c994c20a353906Jim Grosbach    return false;
3195fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach  }
319693b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach  case ARM::tLDMIA: {
319793b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    // Thumb LDM instructions are writeback iff the base register is not
319893b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    // in the register list.
319993b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    unsigned Rn = Inst.getOperand(0).getReg();
32007260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach    bool hasWritebackToken =
32017260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach      (static_cast<ARMOperand*>(Operands[3])->isToken() &&
32027260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach       static_cast<ARMOperand*>(Operands[3])->getToken() == "!");
3203aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    bool listContainsBase;
3204aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase))
3205aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return Error(Operands[3 + hasWritebackToken]->getStartLoc(),
3206aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                   "registers must be in range r0-r7");
320793b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    // If we should have writeback, then there should be a '!' token.
3208aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (!listContainsBase && !hasWritebackToken)
320993b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach      return Error(Operands[2]->getStartLoc(),
321093b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach                   "writeback operator '!' expected");
32117260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach    // Likewise, if we should not have writeback, there must not be a '!'
3212aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (listContainsBase && hasWritebackToken)
32137260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach      return Error(Operands[3]->getStartLoc(),
32147260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach                   "writeback operator '!' not allowed when base register "
32157260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach                   "in register list");
321693b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach
321793b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    break;
321893b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach  }
32196dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  case ARM::tPOP: {
3220aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    bool listContainsBase;
3221aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (checkLowRegisterList(Inst, 3, 0, ARM::PC, listContainsBase))
3222aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return Error(Operands[2]->getStartLoc(),
3223aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                   "registers must be in range r0-r7 or pc");
32246dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach    break;
32256dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  }
32266dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  case ARM::tPUSH: {
3227aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    bool listContainsBase;
3228aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (checkLowRegisterList(Inst, 3, 0, ARM::LR, listContainsBase))
3229aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return Error(Operands[2]->getStartLoc(),
3230aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                   "registers must be in range r0-r7 or lr");
32316dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach    break;
32326dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  }
32331e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach  case ARM::tSTMIA_UPD: {
32341e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach    bool listContainsBase;
3235f95aaf951b628621c9c74bed6c450b8a52a1ae1eJim Grosbach    if (checkLowRegisterList(Inst, 4, 0, 0, listContainsBase))
32361e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach      return Error(Operands[4]->getStartLoc(),
32371e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach                   "registers must be in range r0-r7");
32381e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach    break;
32391e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach  }
3240189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  }
3241189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
3242189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  return false;
3243189610f9466686a91fb7d847b572e1645c785323Jim Grosbach}
3244189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
3245f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbachvoid ARMAsmParser::
3246f8fce711e8b756adca63044f7d122648c960ab96Jim GrosbachprocessInstruction(MCInst &Inst,
3247f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach                   const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3248f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach  switch (Inst.getOpcode()) {
3249f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach  case ARM::LDMIA_UPD:
3250f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    // If this is a load of a single register via a 'pop', then we should use
3251f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    // a post-indexed LDR instruction instead, per the ARM ARM.
3252f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    if (static_cast<ARMOperand*>(Operands[0])->getToken() == "pop" &&
3253f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach        Inst.getNumOperands() == 5) {
3254f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      MCInst TmpInst;
3255f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.setOpcode(ARM::LDR_POST_IMM);
3256f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(4)); // Rt
3257f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
3258f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(1)); // Rn
3259f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));  // am2offset
3260f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(4));
3261f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(2)); // CondCode
3262f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
3263f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      Inst = TmpInst;
3264f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    }
3265f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    break;
3266f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach  case ARM::STMDB_UPD:
3267f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    // If this is a store of a single register via a 'push', then we should use
3268f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    // a pre-indexed STR instruction instead, per the ARM ARM.
3269f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    if (static_cast<ARMOperand*>(Operands[0])->getToken() == "push" &&
3270f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach        Inst.getNumOperands() == 5) {
3271f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      MCInst TmpInst;
3272f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.setOpcode(ARM::STR_PRE_IMM);
3273f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
3274f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(4)); // Rt
3275f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(1)); // addrmode_imm12
3276f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(-4));
3277f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(2)); // CondCode
3278f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
3279f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      Inst = TmpInst;
3280f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    }
3281f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    break;
328289e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach  case ARM::tADDi8:
328389e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach    // If the immediate is in the range 0-7, we really wanted tADDi3.
328489e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach    if (Inst.getOperand(3).getImm() < 8)
328589e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach      Inst.setOpcode(ARM::tADDi3);
328689e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach    break;
3287395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach  case ARM::tBcc:
3288395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach    // If the conditional is AL, we really want tB.
3289395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach    if (Inst.getOperand(1).getImm() == ARMCC::AL)
3290395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach      Inst.setOpcode(ARM::tB);
32913ce23d3d87d1ca437acb65ac01fac1c486507280Jim Grosbach    break;
3292f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach  }
3293f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach}
3294f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach
329547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach// FIXME: We would really prefer to have MCInstrInfo (the wrapper around
329647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach// the ARMInsts array) instead. Getting that here requires awkward
329747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach// API changes, though. Better way?
329847a0d52b69056250a1edaca8b28f705993094542Jim Grosbachnamespace llvm {
329947a0d52b69056250a1edaca8b28f705993094542Jim Grosbachextern MCInstrDesc ARMInsts[];
330047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach}
330147a0d52b69056250a1edaca8b28f705993094542Jim Grosbachstatic MCInstrDesc &getInstDesc(unsigned Opcode) {
330247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  return ARMInsts[Opcode];
330347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach}
330447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach
330547a0d52b69056250a1edaca8b28f705993094542Jim Grosbachunsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
330647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  // 16-bit thumb arithmetic instructions either require or preclude the 'S'
330747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  // suffix depending on whether they're in an IT block or not.
3308194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  unsigned Opc = Inst.getOpcode();
3309194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  MCInstrDesc &MCID = getInstDesc(Opc);
331047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  if (MCID.TSFlags & ARMII::ThumbArithFlagSetting) {
331147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    assert(MCID.hasOptionalDef() &&
331247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach           "optionally flag setting instruction missing optional def operand");
331347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    assert(MCID.NumOperands == Inst.getNumOperands() &&
331447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach           "operand count mismatch!");
331547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // Find the optional-def operand (cc_out).
331647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    unsigned OpNo;
331747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    for (OpNo = 0;
331847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach         !MCID.OpInfo[OpNo].isOptionalDef() && OpNo < MCID.NumOperands;
331947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach         ++OpNo)
332047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach      ;
332147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // If we're parsing Thumb1, reject it completely.
332247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    if (isThumbOne() && Inst.getOperand(OpNo).getReg() != ARM::CPSR)
332347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach      return Match_MnemonicFail;
332447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // If we're parsing Thumb2, which form is legal depends on whether we're
332547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // in an IT block.
332647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // FIXME: We don't yet do IT blocks, so just always consider it to be
332747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // that we aren't in one until we do.
332847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    if (isThumbTwo() && Inst.getOperand(OpNo).getReg() != ARM::CPSR)
332947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach      return Match_RequiresITBlock;
333047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  }
3331194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  // Some high-register supporting Thumb1 encodings only allow both registers
3332194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  // to be from r0-r7 when in Thumb2.
3333194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  else if (Opc == ARM::tADDhirr && isThumbOne() &&
3334194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(1).getReg()) &&
3335194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(2).getReg()))
3336194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Match_RequiresThumb2;
3337194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  // Others only require ARMv6 or later.
33384ec6e888ec6d12b5255afd685b05c8fee1f7fc73Jim Grosbach  else if (Opc == ARM::tMOVr && isThumbOne() && !hasV6Ops() &&
3339194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(0).getReg()) &&
3340194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(1).getReg()))
3341194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Match_RequiresV6;
334247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  return Match_Success;
334347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach}
334447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach
3345fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser::
3346fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc,
3347fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                        SmallVectorImpl<MCParsedAsmOperand*> &Operands,
3348fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                        MCStreamer &Out) {
3349fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  MCInst Inst;
3350fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  unsigned ErrorInfo;
335119cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  unsigned MatchResult;
3352193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo);
3353193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  switch (MatchResult) {
335419cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  default: break;
3355e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_Success:
3356189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // Context sensitive operand constraints aren't handled by the matcher,
3357189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // so check them here.
3358189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    if (validateInstruction(Inst, Operands))
3359189610f9466686a91fb7d847b572e1645c785323Jim Grosbach      return true;
3360189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
3361f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    // Some instructions need post-processing to, for example, tweak which
3362f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    // encoding is selected.
3363f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    processInstruction(Inst, Operands);
3364f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach
3365fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner    Out.EmitInstruction(Inst);
3366fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner    return false;
3367e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_MissingFeature:
3368e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
3369e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return true;
3370e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_InvalidOperand: {
3371e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    SMLoc ErrorLoc = IDLoc;
3372e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    if (ErrorInfo != ~0U) {
3373e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      if (ErrorInfo >= Operands.size())
3374e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner        return Error(IDLoc, "too few operands for instruction");
337516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
3376e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc();
3377e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
3378e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    }
337916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
3380e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return Error(ErrorLoc, "invalid operand for instruction");
3381e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  }
3382e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_MnemonicFail:
338347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    return Error(IDLoc, "invalid instruction");
3384b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar  case Match_ConversionFail:
338588ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    // The converter function will have already emited a diagnostic.
338688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    return true;
338747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  case Match_RequiresITBlock:
338847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    return Error(IDLoc, "instruction only valid inside IT block");
3389194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  case Match_RequiresV6:
3390194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Error(IDLoc, "instruction variant requires ARMv6 or later");
3391194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  case Match_RequiresThumb2:
3392194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Error(IDLoc, "instruction variant requires Thumb2");
3393fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  }
339416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
3395c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher  llvm_unreachable("Implement any new match types added!");
3396146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  return true;
3397fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner}
3398fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner
33991355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirective parses the arm specific directives
3400ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
3401ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  StringRef IDVal = DirectiveID.getIdentifier();
3402ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  if (IDVal == ".word")
34031355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveWord(4, DirectiveID.getLoc());
3404515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".thumb")
34051355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveThumb(DirectiveID.getLoc());
3406515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".thumb_func")
34071355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveThumbFunc(DirectiveID.getLoc());
3408515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".code")
34091355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveCode(DirectiveID.getLoc());
3410515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".syntax")
34111355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveSyntax(DirectiveID.getLoc());
3412ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  return true;
3413ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
3414ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
34151355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveWord
3416ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby///  ::= .word [ expression (, expression)* ]
34171355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
3418ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement)) {
3419ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    for (;;) {
3420ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      const MCExpr *Value;
3421ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getParser().ParseExpression(Value))
3422ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        return true;
3423ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
3424aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner      getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/);
3425ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
3426ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getLexer().is(AsmToken::EndOfStatement))
3427ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        break;
342816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
3429ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      // FIXME: Improve diagnostic.
3430ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getLexer().isNot(AsmToken::Comma))
3431ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        return Error(L, "unexpected token in directive");
3432b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();
3433ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    }
3434ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  }
3435ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
3436b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
3437ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  return false;
3438ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
3439ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
34401355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumb
3441515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .thumb
34421355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumb(SMLoc L) {
3443515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
3444515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in directive");
3445b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
3446515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
3447515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO: set thumb mode
3448515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO: tell the MC streamer the mode
3449515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // getParser().getStreamer().Emit???();
3450515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
3451515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
3452515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
34531355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumbFunc
3454515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .thumbfunc symbol_name
34551355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) {
34566469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo();
34576469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  bool isMachO = MAI.hasSubsectionsViaSymbols();
34586469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  StringRef Name;
34596469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
34606469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // Darwin asm has function name after .thumb_func direction
34616469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // ELF doesn't
34626469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  if (isMachO) {
34636469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    const AsmToken &Tok = Parser.getTok();
34646469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String))
34656469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola      return Error(L, "unexpected token in .thumb_func directive");
34666469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    Name = Tok.getString();
34676469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    Parser.Lex(); // Consume the identifier token.
34686469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  }
34696469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
3470515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
3471515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in directive");
3472b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
3473515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
34746469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // FIXME: assuming function name will be the line following .thumb_func
34756469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  if (!isMachO) {
34766469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    Name = Parser.getTok().getString();
34776469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  }
34786469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
3479642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  // Mark symbol as a thumb symbol.
3480642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name);
3481642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  getParser().getStreamer().EmitThumbFunc(Func);
3482515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
3483515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
3484515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
34851355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveSyntax
3486515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .syntax unified | divided
34871355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveSyntax(SMLoc L) {
348818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
3489515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Identifier))
3490515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .syntax directive");
349138e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  StringRef Mode = Tok.getString();
349258c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  if (Mode == "unified" || Mode == "UNIFIED")
3493b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
349458c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  else if (Mode == "divided" || Mode == "DIVIDED")
34959e56fb12c504c82c92947fe9c46287fc60116b91Kevin Enderby    return Error(L, "'.syntax divided' arm asssembly not supported");
3496515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else
3497515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unrecognized syntax mode in .syntax directive");
3498515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
3499515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
350018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
3501b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
3502515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
3503515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO tell the MC streamer the mode
3504515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // getParser().getStreamer().Emit???();
3505515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
3506515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
3507515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
35081355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveCode
3509515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .code 16 | 32
35101355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveCode(SMLoc L) {
351118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
3512515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Integer))
3513515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .code directive");
351418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  int64_t Val = Parser.getTok().getIntVal();
351558c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  if (Val == 16)
3516b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
351758c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  else if (Val == 32)
3518b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
3519515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else
3520515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "invalid operand to .code directive");
3521515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
3522515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
352318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
3524b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
3525515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
352632869205052430f45d598fba25ab878d8b29da2dEvan Cheng  if (Val == 16) {
3527bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    if (!isThumb()) {
3528ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng      SwitchMode();
3529bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng      getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
3530bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    }
353132869205052430f45d598fba25ab878d8b29da2dEvan Cheng  } else {
3532bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    if (isThumb()) {
3533ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng      SwitchMode();
3534bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng      getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
3535bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    }
3536eb0caa115491019f7f7fe45fc70ad47682244187Evan Cheng  }
35372a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach
3538515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
3539515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
3540515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
354190b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer();
354290b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan
35439c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization.
3544ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() {
354594b9550a32d189704a8eae55505edf62662c0534Evan Cheng  RegisterMCAsmParser<ARMAsmParser> X(TheARMTarget);
354694b9550a32d189704a8eae55505edf62662c0534Evan Cheng  RegisterMCAsmParser<ARMAsmParser> Y(TheThumbTarget);
354790b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan  LLVMInitializeARMAsmLexer();
3548ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
35493483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
35500692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER
35510692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION
35523483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc"
3553