ARMAsmParser.cpp revision 226633
1185377Ssam//===-- ARMAsmParser.cpp - Parse ARM assembly to MCInst instructions ------===//
2187831Ssam//
3185377Ssam//                     The LLVM Compiler Infrastructure
4185377Ssam//
5185377Ssam// This file is distributed under the University of Illinois Open Source
6185377Ssam// License. See LICENSE.TXT for details.
7185377Ssam//
8185377Ssam//===----------------------------------------------------------------------===//
9185377Ssam
10185377Ssam#include "MCTargetDesc/ARMBaseInfo.h"
11185377Ssam#include "MCTargetDesc/ARMAddressingModes.h"
12185377Ssam#include "MCTargetDesc/ARMMCExpr.h"
13185377Ssam#include "llvm/MC/MCParser/MCAsmLexer.h"
14185377Ssam#include "llvm/MC/MCParser/MCAsmParser.h"
15185377Ssam#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
16185377Ssam#include "llvm/MC/MCAsmInfo.h"
17185377Ssam#include "llvm/MC/MCContext.h"
18187345Ssam#include "llvm/MC/MCStreamer.h"
19185377Ssam#include "llvm/MC/MCExpr.h"
20185377Ssam#include "llvm/MC/MCInst.h"
21185377Ssam#include "llvm/MC/MCInstrDesc.h"
22185377Ssam#include "llvm/MC/MCRegisterInfo.h"
23187831Ssam#include "llvm/MC/MCSubtargetInfo.h"
24187831Ssam#include "llvm/MC/MCTargetAsmParser.h"
25187831Ssam#include "llvm/Support/MathExtras.h"
26187831Ssam#include "llvm/Support/SourceMgr.h"
27185377Ssam#include "llvm/Support/TargetRegistry.h"
28185377Ssam#include "llvm/Support/raw_ostream.h"
29185377Ssam#include "llvm/ADT/BitVector.h"
30185377Ssam#include "llvm/ADT/OwningPtr.h"
31185377Ssam#include "llvm/ADT/STLExtras.h"
32185377Ssam#include "llvm/ADT/SmallVector.h"
33185377Ssam#include "llvm/ADT/StringExtras.h"
34185377Ssam#include "llvm/ADT/StringSwitch.h"
35185377Ssam#include "llvm/ADT/Twine.h"
36185377Ssam
37185377Ssamusing namespace llvm;
38185377Ssam
39185377Ssamnamespace {
40185377Ssam
41185377Ssamclass ARMOperand;
42185380Ssam
43185380Ssamclass ARMAsmParser : public MCTargetAsmParser {
44185380Ssam  MCSubtargetInfo &STI;
45185380Ssam  MCAsmParser &Parser;
46185377Ssam
47185380Ssam  struct {
48185380Ssam    ARMCC::CondCodes Cond;    // Condition for IT block.
49185377Ssam    unsigned Mask:4;          // Condition mask for instructions.
50185380Ssam                              // Starting at first 1 (from lsb).
51185380Ssam                              //   '1'  condition as indicated in IT.
52185380Ssam                              //   '0'  inverse of condition (else).
53185380Ssam                              // Count of instructions in IT block is
54185380Ssam                              // 4 - trailingzeroes(mask)
55185380Ssam
56185380Ssam    bool FirstCond;           // Explicit flag for when we're parsing the
57185380Ssam                              // First instruction in the IT block. It's
58185380Ssam                              // implied in the mask, so needs special
59185380Ssam                              // handling.
60185380Ssam
61185380Ssam    unsigned CurPosition;     // Current position in parsing of IT
62185380Ssam                              // block. In range [0,3]. Initialized
63185380Ssam                              // according to count of instructions in block.
64185380Ssam                              // ~0U if no active IT block.
65185380Ssam  } ITState;
66185380Ssam  bool inITBlock() { return ITState.CurPosition != ~0U;}
67185380Ssam  void forwardITPosition() {
68185380Ssam    if (!inITBlock()) return;
69185380Ssam    // Move to the next instruction in the IT block, if there is one. If not,
70185380Ssam    // mark the block as done.
71185380Ssam    unsigned TZ = CountTrailingZeros_32(ITState.Mask);
72185380Ssam    if (++ITState.CurPosition == 5 - TZ)
73185380Ssam      ITState.CurPosition = ~0U; // Done with the IT block after this.
74185380Ssam  }
75185380Ssam
76185380Ssam
77185377Ssam  MCAsmParser &getParser() const { return Parser; }
78185377Ssam  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
79185380Ssam
80185380Ssam  void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }
81185377Ssam  bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
82185377Ssam
83185380Ssam  int tryParseRegister();
84185380Ssam  bool tryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &);
85185377Ssam  int tryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &);
86185377Ssam  bool parseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &);
87185377Ssam  bool parseMemory(SmallVectorImpl<MCParsedAsmOperand*> &);
88185377Ssam  bool parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic);
89185380Ssam  bool parsePrefix(ARMMCExpr::VariantKind &RefKind);
90185377Ssam  bool parseMemRegOffsetShift(ARM_AM::ShiftOpc &ShiftType,
91185377Ssam                              unsigned &ShiftAmount);
92185377Ssam  bool parseDirectiveWord(unsigned Size, SMLoc L);
93185377Ssam  bool parseDirectiveThumb(SMLoc L);
94185377Ssam  bool parseDirectiveThumbFunc(SMLoc L);
95185377Ssam  bool parseDirectiveCode(SMLoc L);
96185377Ssam  bool parseDirectiveSyntax(SMLoc L);
97185377Ssam
98185377Ssam  StringRef splitMnemonic(StringRef Mnemonic, unsigned &PredicationCode,
99185377Ssam                          bool &CarrySetting, unsigned &ProcessorIMod,
100185377Ssam                          StringRef &ITMask);
101185377Ssam  void getMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
102185377Ssam                             bool &CanAcceptPredicationCode);
103185377Ssam
104185377Ssam  bool isThumb() const {
105185377Ssam    // FIXME: Can tablegen auto-generate this?
106185377Ssam    return (STI.getFeatureBits() & ARM::ModeThumb) != 0;
107185380Ssam  }
108185377Ssam  bool isThumbOne() const {
109185377Ssam    return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) == 0;
110185377Ssam  }
111185377Ssam  bool isThumbTwo() const {
112185377Ssam    return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2);
113185377Ssam  }
114185377Ssam  bool hasV6Ops() const {
115185377Ssam    return STI.getFeatureBits() & ARM::HasV6Ops;
116185377Ssam  }
117185377Ssam  bool hasV7Ops() const {
118185377Ssam    return STI.getFeatureBits() & ARM::HasV7Ops;
119185377Ssam  }
120185377Ssam  void SwitchMode() {
121185377Ssam    unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb));
122185377Ssam    setAvailableFeatures(FB);
123185377Ssam  }
124185377Ssam  bool isMClass() const {
125185377Ssam    return STI.getFeatureBits() & ARM::FeatureMClass;
126185377Ssam  }
127185377Ssam
128185377Ssam  /// @name Auto-generated Match Functions
129185377Ssam  /// {
130185377Ssam
131185377Ssam#define GET_ASSEMBLER_HEADER
132185377Ssam#include "ARMGenAsmMatcher.inc"
133185377Ssam
134185377Ssam  /// }
135185377Ssam
136185377Ssam  OperandMatchResultTy parseITCondCode(SmallVectorImpl<MCParsedAsmOperand*>&);
137185377Ssam  OperandMatchResultTy parseCoprocNumOperand(
138185377Ssam    SmallVectorImpl<MCParsedAsmOperand*>&);
139185377Ssam  OperandMatchResultTy parseCoprocRegOperand(
140185377Ssam    SmallVectorImpl<MCParsedAsmOperand*>&);
141185377Ssam  OperandMatchResultTy parseCoprocOptionOperand(
142185377Ssam    SmallVectorImpl<MCParsedAsmOperand*>&);
143185377Ssam  OperandMatchResultTy parseMemBarrierOptOperand(
144185377Ssam    SmallVectorImpl<MCParsedAsmOperand*>&);
145185377Ssam  OperandMatchResultTy parseProcIFlagsOperand(
146185377Ssam    SmallVectorImpl<MCParsedAsmOperand*>&);
147185377Ssam  OperandMatchResultTy parseMSRMaskOperand(
148187831Ssam    SmallVectorImpl<MCParsedAsmOperand*>&);
149187831Ssam  OperandMatchResultTy parsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &O,
150187831Ssam                                   StringRef Op, int Low, int High);
151185377Ssam  OperandMatchResultTy parsePKHLSLImm(SmallVectorImpl<MCParsedAsmOperand*> &O) {
152185377Ssam    return parsePKHImm(O, "lsl", 0, 31);
153185377Ssam  }
154185377Ssam  OperandMatchResultTy parsePKHASRImm(SmallVectorImpl<MCParsedAsmOperand*> &O) {
155185377Ssam    return parsePKHImm(O, "asr", 1, 32);
156185377Ssam  }
157185377Ssam  OperandMatchResultTy parseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*>&);
158185377Ssam  OperandMatchResultTy parseShifterImm(SmallVectorImpl<MCParsedAsmOperand*>&);
159185377Ssam  OperandMatchResultTy parseRotImm(SmallVectorImpl<MCParsedAsmOperand*>&);
160185377Ssam  OperandMatchResultTy parseBitfield(SmallVectorImpl<MCParsedAsmOperand*>&);
161185377Ssam  OperandMatchResultTy parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*>&);
162185377Ssam  OperandMatchResultTy parseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*>&);
163185377Ssam  OperandMatchResultTy parseFPImm(SmallVectorImpl<MCParsedAsmOperand*>&);
164185377Ssam
165185377Ssam  // Asm Match Converter Methods
166185377Ssam  bool cvtT2LdrdPre(MCInst &Inst, unsigned Opcode,
167185377Ssam                    const SmallVectorImpl<MCParsedAsmOperand*> &);
168185377Ssam  bool cvtT2StrdPre(MCInst &Inst, unsigned Opcode,
169185377Ssam                    const SmallVectorImpl<MCParsedAsmOperand*> &);
170185377Ssam  bool cvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
171185377Ssam                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
172185377Ssam  bool cvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
173185377Ssam                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
174185377Ssam  bool cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
175185377Ssam                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
176185377Ssam  bool cvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
177185377Ssam                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
178185377Ssam  bool cvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
179185377Ssam                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
180185377Ssam  bool cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
181185377Ssam                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
182185377Ssam  bool cvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
183185377Ssam                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
184185377Ssam  bool cvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
185185377Ssam                             const SmallVectorImpl<MCParsedAsmOperand*> &);
186185377Ssam  bool cvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
187185377Ssam                             const SmallVectorImpl<MCParsedAsmOperand*> &);
188185377Ssam  bool cvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
189185377Ssam                             const SmallVectorImpl<MCParsedAsmOperand*> &);
190185377Ssam  bool cvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
191185377Ssam                             const SmallVectorImpl<MCParsedAsmOperand*> &);
192185377Ssam  bool cvtLdrdPre(MCInst &Inst, unsigned Opcode,
193185377Ssam                  const SmallVectorImpl<MCParsedAsmOperand*> &);
194185377Ssam  bool cvtStrdPre(MCInst &Inst, unsigned Opcode,
195185377Ssam                  const SmallVectorImpl<MCParsedAsmOperand*> &);
196185377Ssam  bool cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
197185377Ssam                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
198185377Ssam  bool cvtThumbMultiply(MCInst &Inst, unsigned Opcode,
199185377Ssam                        const SmallVectorImpl<MCParsedAsmOperand*> &);
200185377Ssam
201185377Ssam  bool validateInstruction(MCInst &Inst,
202185377Ssam                           const SmallVectorImpl<MCParsedAsmOperand*> &Ops);
203185377Ssam  void processInstruction(MCInst &Inst,
204185377Ssam                          const SmallVectorImpl<MCParsedAsmOperand*> &Ops);
205185377Ssam  bool shouldOmitCCOutOperand(StringRef Mnemonic,
206185377Ssam                              SmallVectorImpl<MCParsedAsmOperand*> &Operands);
207185377Ssam
208185377Ssampublic:
209185377Ssam  enum ARMMatchResultTy {
210185377Ssam    Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY,
211185377Ssam    Match_RequiresNotITBlock,
212185377Ssam    Match_RequiresV6,
213185377Ssam    Match_RequiresThumb2
214185377Ssam  };
215185377Ssam
216185377Ssam  ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser)
217185377Ssam    : MCTargetAsmParser(), STI(_STI), Parser(_Parser) {
218185377Ssam    MCAsmParserExtension::Initialize(_Parser);
219185377Ssam
220185377Ssam    // Initialize the set of available features.
221185377Ssam    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
222185377Ssam
223185377Ssam    // Not in an ITBlock to start with.
224185377Ssam    ITState.CurPosition = ~0U;
225185377Ssam  }
226185377Ssam
227185377Ssam  // Implementation of the MCTargetAsmParser interface:
228185377Ssam  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
229185377Ssam  bool ParseInstruction(StringRef Name, SMLoc NameLoc,
230185377Ssam                        SmallVectorImpl<MCParsedAsmOperand*> &Operands);
231185377Ssam  bool ParseDirective(AsmToken DirectiveID);
232185377Ssam
233185377Ssam  unsigned checkTargetMatchPredicate(MCInst &Inst);
234185377Ssam
235185380Ssam  bool MatchAndEmitInstruction(SMLoc IDLoc,
236185377Ssam                               SmallVectorImpl<MCParsedAsmOperand*> &Operands,
237185380Ssam                               MCStreamer &Out);
238185377Ssam};
239185377Ssam} // end anonymous namespace
240185377Ssam
241185377Ssamnamespace {
242185377Ssam
243185377Ssam/// ARMOperand - Instances of this class represent a parsed ARM machine
244185377Ssam/// instruction.
245185377Ssamclass ARMOperand : public MCParsedAsmOperand {
246185377Ssam  enum KindTy {
247185377Ssam    k_CondCode,
248185377Ssam    k_CCOut,
249185377Ssam    k_ITCondMask,
250185377Ssam    k_CoprocNum,
251185377Ssam    k_CoprocReg,
252185377Ssam    k_CoprocOption,
253185377Ssam    k_Immediate,
254185377Ssam    k_FPImmediate,
255185377Ssam    k_MemBarrierOpt,
256185377Ssam    k_Memory,
257185377Ssam    k_PostIndexRegister,
258185377Ssam    k_MSRMask,
259185377Ssam    k_ProcIFlags,
260185377Ssam    k_VectorIndex,
261185377Ssam    k_Register,
262185377Ssam    k_RegisterList,
263185377Ssam    k_DPRRegisterList,
264185377Ssam    k_SPRRegisterList,
265185377Ssam    k_ShiftedRegister,
266185377Ssam    k_ShiftedImmediate,
267185377Ssam    k_ShifterImmediate,
268185377Ssam    k_RotateImmediate,
269185377Ssam    k_BitfieldDescriptor,
270185377Ssam    k_Token
271185380Ssam  } Kind;
272185377Ssam
273185377Ssam  SMLoc StartLoc, EndLoc;
274185380Ssam  SmallVector<unsigned, 8> Registers;
275187831Ssam
276187831Ssam  union {
277187831Ssam    struct {
278187831Ssam      ARMCC::CondCodes Val;
279187831Ssam    } CC;
280185380Ssam
281185377Ssam    struct {
282185377Ssam      unsigned Val;
283185377Ssam    } Cop;
284185377Ssam
285185377Ssam    struct {
286185377Ssam      unsigned Val;
287185380Ssam    } CoprocOption;
288185377Ssam
289185377Ssam    struct {
290185377Ssam      unsigned Mask:4;
291185377Ssam    } ITMask;
292185377Ssam
293185377Ssam    struct {
294185377Ssam      ARM_MB::MemBOpt Val;
295185377Ssam    } MBOpt;
296185377Ssam
297185377Ssam    struct {
298185377Ssam      ARM_PROC::IFlags Val;
299185377Ssam    } IFlags;
300185377Ssam
301185377Ssam    struct {
302185377Ssam      unsigned Val;
303185377Ssam    } MMask;
304185377Ssam
305185377Ssam    struct {
306185377Ssam      const char *Data;
307185377Ssam      unsigned Length;
308185377Ssam    } Tok;
309185377Ssam
310185377Ssam    struct {
311187831Ssam      unsigned RegNum;
312185377Ssam    } Reg;
313185377Ssam
314185377Ssam    struct {
315185377Ssam      unsigned Val;
316185377Ssam    } VectorIndex;
317185377Ssam
318185377Ssam    struct {
319185377Ssam      const MCExpr *Val;
320185377Ssam    } Imm;
321185377Ssam
322185377Ssam    struct {
323185377Ssam      unsigned Val;       // encoded 8-bit representation
324185377Ssam    } FPImm;
325185377Ssam
326185377Ssam    /// Combined record for all forms of ARM address expressions.
327185377Ssam    struct {
328185377Ssam      unsigned BaseRegNum;
329185377Ssam      // Offset is in OffsetReg or OffsetImm. If both are zero, no offset
330185377Ssam      // was specified.
331187831Ssam      const MCConstantExpr *OffsetImm;  // Offset immediate value
332187831Ssam      unsigned OffsetRegNum;    // Offset register num, when OffsetImm == NULL
333187831Ssam      ARM_AM::ShiftOpc ShiftType; // Shift type for OffsetReg
334187831Ssam      unsigned ShiftImm;        // shift for OffsetReg.
335185377Ssam      unsigned Alignment;       // 0 = no alignment specified
336187831Ssam                                // n = alignment in bytes (8, 16, or 32)
337187831Ssam      unsigned isNegative : 1;  // Negated OffsetReg? (~'U' bit)
338187831Ssam    } Memory;
339187831Ssam
340187831Ssam    struct {
341187831Ssam      unsigned RegNum;
342187831Ssam      bool isAdd;
343185377Ssam      ARM_AM::ShiftOpc ShiftTy;
344187831Ssam      unsigned ShiftImm;
345187831Ssam    } PostIdxReg;
346187831Ssam
347187831Ssam    struct {
348187831Ssam      bool isASR;
349187831Ssam      unsigned Imm;
350185377Ssam    } ShifterImm;
351187831Ssam    struct {
352187831Ssam      ARM_AM::ShiftOpc ShiftTy;
353185377Ssam      unsigned SrcReg;
354187831Ssam      unsigned ShiftReg;
355187831Ssam      unsigned ShiftImm;
356187831Ssam    } RegShiftedReg;
357187831Ssam    struct {
358187831Ssam      ARM_AM::ShiftOpc ShiftTy;
359187831Ssam      unsigned SrcReg;
360187831Ssam      unsigned ShiftImm;
361187831Ssam    } RegShiftedImm;
362187831Ssam    struct {
363187831Ssam      unsigned Imm;
364185377Ssam    } RotImm;
365187831Ssam    struct {
366187831Ssam      unsigned LSB;
367187831Ssam      unsigned Width;
368187831Ssam    } Bitfield;
369185377Ssam  };
370185377Ssam
371185377Ssam  ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
372185377Ssampublic:
373185377Ssam  ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() {
374185377Ssam    Kind = o.Kind;
375185377Ssam    StartLoc = o.StartLoc;
376185377Ssam    EndLoc = o.EndLoc;
377185377Ssam    switch (Kind) {
378185377Ssam    case k_CondCode:
379185377Ssam      CC = o.CC;
380185377Ssam      break;
381187831Ssam    case k_ITCondMask:
382185377Ssam      ITMask = o.ITMask;
383187831Ssam      break;
384185377Ssam    case k_Token:
385185377Ssam      Tok = o.Tok;
386187831Ssam      break;
387185377Ssam    case k_CCOut:
388185377Ssam    case k_Register:
389185377Ssam      Reg = o.Reg;
390187831Ssam      break;
391185377Ssam    case k_RegisterList:
392185377Ssam    case k_DPRRegisterList:
393187831Ssam    case k_SPRRegisterList:
394185377Ssam      Registers = o.Registers;
395185377Ssam      break;
396185377Ssam    case k_CoprocNum:
397185377Ssam    case k_CoprocReg:
398185377Ssam      Cop = o.Cop;
399185377Ssam      break;
400185377Ssam    case k_CoprocOption:
401185377Ssam      CoprocOption = o.CoprocOption;
402185377Ssam      break;
403185377Ssam    case k_Immediate:
404185377Ssam      Imm = o.Imm;
405185377Ssam      break;
406185377Ssam    case k_FPImmediate:
407185377Ssam      FPImm = o.FPImm;
408185377Ssam      break;
409185377Ssam    case k_MemBarrierOpt:
410185377Ssam      MBOpt = o.MBOpt;
411185377Ssam      break;
412185377Ssam    case k_Memory:
413185377Ssam      Memory = o.Memory;
414185377Ssam      break;
415187831Ssam    case k_PostIndexRegister:
416187831Ssam      PostIdxReg = o.PostIdxReg;
417185377Ssam      break;
418185377Ssam    case k_MSRMask:
419187831Ssam      MMask = o.MMask;
420187831Ssam      break;
421187831Ssam    case k_ProcIFlags:
422187831Ssam      IFlags = o.IFlags;
423187831Ssam      break;
424187831Ssam    case k_ShifterImmediate:
425187831Ssam      ShifterImm = o.ShifterImm;
426187831Ssam      break;
427187831Ssam    case k_ShiftedRegister:
428187831Ssam      RegShiftedReg = o.RegShiftedReg;
429187831Ssam      break;
430185377Ssam    case k_ShiftedImmediate:
431185377Ssam      RegShiftedImm = o.RegShiftedImm;
432185377Ssam      break;
433185380Ssam    case k_RotateImmediate:
434185377Ssam      RotImm = o.RotImm;
435185377Ssam      break;
436185377Ssam    case k_BitfieldDescriptor:
437185377Ssam      Bitfield = o.Bitfield;
438185377Ssam      break;
439185377Ssam    case k_VectorIndex:
440185377Ssam      VectorIndex = o.VectorIndex;
441185377Ssam      break;
442185377Ssam    }
443185377Ssam  }
444185377Ssam
445185377Ssam  /// getStartLoc - Get the location of the first token of this operand.
446185377Ssam  SMLoc getStartLoc() const { return StartLoc; }
447185377Ssam  /// getEndLoc - Get the location of the last token of this operand.
448187831Ssam  SMLoc getEndLoc() const { return EndLoc; }
449187831Ssam
450187831Ssam  ARMCC::CondCodes getCondCode() const {
451187831Ssam    assert(Kind == k_CondCode && "Invalid access!");
452187831Ssam    return CC.Val;
453187831Ssam  }
454187831Ssam
455187831Ssam  unsigned getCoproc() const {
456187831Ssam    assert((Kind == k_CoprocNum || Kind == k_CoprocReg) && "Invalid access!");
457187831Ssam    return Cop.Val;
458187831Ssam  }
459187831Ssam
460187831Ssam  StringRef getToken() const {
461187831Ssam    assert(Kind == k_Token && "Invalid access!");
462187831Ssam    return StringRef(Tok.Data, Tok.Length);
463187831Ssam  }
464187831Ssam
465187831Ssam  unsigned getReg() const {
466187831Ssam    assert((Kind == k_Register || Kind == k_CCOut) && "Invalid access!");
467187831Ssam    return Reg.RegNum;
468187831Ssam  }
469187831Ssam
470187831Ssam  const SmallVectorImpl<unsigned> &getRegList() const {
471187831Ssam    assert((Kind == k_RegisterList || Kind == k_DPRRegisterList ||
472187831Ssam            Kind == k_SPRRegisterList) && "Invalid access!");
473187831Ssam    return Registers;
474187831Ssam  }
475187831Ssam
476187831Ssam  const MCExpr *getImm() const {
477187831Ssam    assert(Kind == k_Immediate && "Invalid access!");
478187831Ssam    return Imm.Val;
479187831Ssam  }
480187831Ssam
481187831Ssam  unsigned getFPImm() const {
482187831Ssam    assert(Kind == k_FPImmediate && "Invalid access!");
483187831Ssam    return FPImm.Val;
484187831Ssam  }
485187831Ssam
486187831Ssam  unsigned getVectorIndex() const {
487187831Ssam    assert(Kind == k_VectorIndex && "Invalid access!");
488187831Ssam    return VectorIndex.Val;
489187831Ssam  }
490187831Ssam
491187831Ssam  ARM_MB::MemBOpt getMemBarrierOpt() const {
492187831Ssam    assert(Kind == k_MemBarrierOpt && "Invalid access!");
493187831Ssam    return MBOpt.Val;
494187831Ssam  }
495187831Ssam
496187831Ssam  ARM_PROC::IFlags getProcIFlags() const {
497187831Ssam    assert(Kind == k_ProcIFlags && "Invalid access!");
498187831Ssam    return IFlags.Val;
499187831Ssam  }
500187831Ssam
501187831Ssam  unsigned getMSRMask() const {
502187831Ssam    assert(Kind == k_MSRMask && "Invalid access!");
503185377Ssam    return MMask.Val;
504187831Ssam  }
505187831Ssam
506187831Ssam  bool isCoprocNum() const { return Kind == k_CoprocNum; }
507185377Ssam  bool isCoprocReg() const { return Kind == k_CoprocReg; }
508187831Ssam  bool isCoprocOption() const { return Kind == k_CoprocOption; }
509187831Ssam  bool isCondCode() const { return Kind == k_CondCode; }
510187831Ssam  bool isCCOut() const { return Kind == k_CCOut; }
511185377Ssam  bool isITMask() const { return Kind == k_ITCondMask; }
512187831Ssam  bool isITCondCode() const { return Kind == k_CondCode; }
513187831Ssam  bool isImm() const { return Kind == k_Immediate; }
514187831Ssam  bool isFPImm() const { return Kind == k_FPImmediate; }
515185377Ssam  bool isImm8s4() const {
516187831Ssam    if (Kind != k_Immediate)
517187831Ssam      return false;
518187831Ssam    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
519185377Ssam    if (!CE) return false;
520187831Ssam    int64_t Value = CE->getValue();
521187831Ssam    return ((Value & 3) == 0) && Value >= -1020 && Value <= 1020;
522187831Ssam  }
523185377Ssam  bool isImm0_1020s4() const {
524187831Ssam    if (Kind != k_Immediate)
525187831Ssam      return false;
526187831Ssam    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
527185377Ssam    if (!CE) return false;
528187831Ssam    int64_t Value = CE->getValue();
529187831Ssam    return ((Value & 3) == 0) && Value >= 0 && Value <= 1020;
530187831Ssam  }
531187831Ssam  bool isImm0_508s4() const {
532187831Ssam    if (Kind != k_Immediate)
533187831Ssam      return false;
534187831Ssam    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
535187831Ssam    if (!CE) return false;
536187831Ssam    int64_t Value = CE->getValue();
537187831Ssam    return ((Value & 3) == 0) && Value >= 0 && Value <= 508;
538187831Ssam  }
539187831Ssam  bool isImm0_255() const {
540187831Ssam    if (Kind != k_Immediate)
541187831Ssam      return false;
542187831Ssam    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
543187831Ssam    if (!CE) return false;
544187831Ssam    int64_t Value = CE->getValue();
545187831Ssam    return Value >= 0 && Value < 256;
546187831Ssam  }
547187831Ssam  bool isImm0_7() const {
548187831Ssam    if (Kind != k_Immediate)
549187831Ssam      return false;
550187831Ssam    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
551187831Ssam    if (!CE) return false;
552187831Ssam    int64_t Value = CE->getValue();
553187831Ssam    return Value >= 0 && Value < 8;
554187831Ssam  }
555187831Ssam  bool isImm0_15() const {
556187831Ssam    if (Kind != k_Immediate)
557187831Ssam      return false;
558187831Ssam    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
559187831Ssam    if (!CE) return false;
560187831Ssam    int64_t Value = CE->getValue();
561187831Ssam    return Value >= 0 && Value < 16;
562187831Ssam  }
563187831Ssam  bool isImm0_31() const {
564187831Ssam    if (Kind != k_Immediate)
565187831Ssam      return false;
566187831Ssam    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
567187831Ssam    if (!CE) return false;
568187831Ssam    int64_t Value = CE->getValue();
569187831Ssam    return Value >= 0 && Value < 32;
570187831Ssam  }
571187831Ssam  bool isImm1_16() const {
572187831Ssam    if (Kind != k_Immediate)
573187831Ssam      return false;
574187831Ssam    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
575187831Ssam    if (!CE) return false;
576187831Ssam    int64_t Value = CE->getValue();
577187831Ssam    return Value > 0 && Value < 17;
578187831Ssam  }
579187831Ssam  bool isImm1_32() const {
580187831Ssam    if (Kind != k_Immediate)
581187831Ssam      return false;
582187831Ssam    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
583187831Ssam    if (!CE) return false;
584187831Ssam    int64_t Value = CE->getValue();
585185377Ssam    return Value > 0 && Value < 33;
586185377Ssam  }
587185380Ssam  bool isImm0_65535() const {
588185380Ssam    if (Kind != k_Immediate)
589185380Ssam      return false;
590185380Ssam    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
591185380Ssam    if (!CE) return false;
592185380Ssam    int64_t Value = CE->getValue();
593185380Ssam    return Value >= 0 && Value < 65536;
594185380Ssam  }
595185380Ssam  bool isImm0_65535Expr() const {
596185380Ssam    if (Kind != k_Immediate)
597185380Ssam      return false;
598185380Ssam    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
599185380Ssam    // If it's not a constant expression, it'll generate a fixup and be
600185380Ssam    // handled later.
601185380Ssam    if (!CE) return true;
602185380Ssam    int64_t Value = CE->getValue();
603185380Ssam    return Value >= 0 && Value < 65536;
604185380Ssam  }
605185380Ssam  bool isImm24bit() const {
606185380Ssam    if (Kind != k_Immediate)
607185380Ssam      return false;
608185380Ssam    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
609185380Ssam    if (!CE) return false;
610185380Ssam    int64_t Value = CE->getValue();
611185377Ssam    return Value >= 0 && Value <= 0xffffff;
612185377Ssam  }
613185377Ssam  bool isImmThumbSR() const {
614185377Ssam    if (Kind != k_Immediate)
615185377Ssam      return false;
616185377Ssam    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
617185377Ssam    if (!CE) return false;
618185377Ssam    int64_t Value = CE->getValue();
619185377Ssam    return Value > 0 && Value < 33;
620185377Ssam  }
621185377Ssam  bool isPKHLSLImm() const {
622185377Ssam    if (Kind != k_Immediate)
623185377Ssam      return false;
624185377Ssam    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
625185377Ssam    if (!CE) return false;
626185377Ssam    int64_t Value = CE->getValue();
627185377Ssam    return Value >= 0 && Value < 32;
628185377Ssam  }
629187831Ssam  bool isPKHASRImm() const {
630185380Ssam    if (Kind != k_Immediate)
631187831Ssam      return false;
632185380Ssam    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
633187831Ssam    if (!CE) return false;
634185380Ssam    int64_t Value = CE->getValue();
635187831Ssam    return Value > 0 && Value <= 32;
636185380Ssam  }
637187831Ssam  bool isARMSOImm() const {
638185380Ssam    if (Kind != k_Immediate)
639187831Ssam      return false;
640185380Ssam    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
641187831Ssam    if (!CE) return false;
642185380Ssam    int64_t Value = CE->getValue();
643187831Ssam    return ARM_AM::getSOImmVal(Value) != -1;
644185380Ssam  }
645187831Ssam  bool isT2SOImm() const {
646185380Ssam    if (Kind != k_Immediate)
647185377Ssam      return false;
648187831Ssam    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
649185380Ssam    if (!CE) return false;
650187831Ssam    int64_t Value = CE->getValue();
651185380Ssam    return ARM_AM::getT2SOImmVal(Value) != -1;
652187831Ssam  }
653185380Ssam  bool isSetEndImm() const {
654185377Ssam    if (Kind != k_Immediate)
655187831Ssam      return false;
656185380Ssam    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
657187831Ssam    if (!CE) return false;
658185380Ssam    int64_t Value = CE->getValue();
659185377Ssam    return Value == 1 || Value == 0;
660187831Ssam  }
661185380Ssam  bool isReg() const { return Kind == k_Register; }
662187831Ssam  bool isRegList() const { return Kind == k_RegisterList; }
663185380Ssam  bool isDPRRegList() const { return Kind == k_DPRRegisterList; }
664187831Ssam  bool isSPRRegList() const { return Kind == k_SPRRegisterList; }
665185380Ssam  bool isToken() const { return Kind == k_Token; }
666187831Ssam  bool isMemBarrierOpt() const { return Kind == k_MemBarrierOpt; }
667185380Ssam  bool isMemory() const { return Kind == k_Memory; }
668187831Ssam  bool isShifterImm() const { return Kind == k_ShifterImmediate; }
669185380Ssam  bool isRegShiftedReg() const { return Kind == k_ShiftedRegister; }
670187831Ssam  bool isRegShiftedImm() const { return Kind == k_ShiftedImmediate; }
671185380Ssam  bool isRotImm() const { return Kind == k_RotateImmediate; }
672187831Ssam  bool isBitfield() const { return Kind == k_BitfieldDescriptor; }
673185380Ssam  bool isPostIdxRegShifted() const { return Kind == k_PostIndexRegister; }
674187831Ssam  bool isPostIdxReg() const {
675185380Ssam    return Kind == k_PostIndexRegister && PostIdxReg.ShiftTy == ARM_AM::no_shift;
676187831Ssam  }
677185377Ssam  bool isMemNoOffset(bool alignOK = false) const {
678185380Ssam    if (!isMemory())
679187831Ssam      return false;
680185377Ssam    // No offset of any kind.
681185380Ssam    return Memory.OffsetRegNum == 0 && Memory.OffsetImm == 0 &&
682187831Ssam     (alignOK || Memory.Alignment == 0);
683185377Ssam  }
684185380Ssam  bool isAlignedMemory() const {
685187831Ssam    return isMemNoOffset(true);
686185377Ssam  }
687185380Ssam  bool isAddrMode2() const {
688187831Ssam    if (!isMemory() || Memory.Alignment != 0) return false;
689185380Ssam    // Check for register offset.
690185377Ssam    if (Memory.OffsetRegNum) return true;
691187831Ssam    // Immediate offset in range [-4095, 4095].
692185380Ssam    if (!Memory.OffsetImm) return true;
693187831Ssam    int64_t Val = Memory.OffsetImm->getValue();
694185380Ssam    return Val > -4096 && Val < 4096;
695187831Ssam  }
696185380Ssam  bool isAM2OffsetImm() const {
697187831Ssam    if (Kind != k_Immediate)
698185380Ssam      return false;
699187831Ssam    // Immediate offset in range [-4095, 4095].
700185380Ssam    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
701187831Ssam    if (!CE) return false;
702185380Ssam    int64_t Val = CE->getValue();
703185377Ssam    return Val > -4096 && Val < 4096;
704187831Ssam  }
705185380Ssam  bool isAddrMode3() const {
706187831Ssam    if (!isMemory() || Memory.Alignment != 0) return false;
707185380Ssam    // No shifts are legal for AM3.
708187831Ssam    if (Memory.ShiftType != ARM_AM::no_shift) return false;
709185380Ssam    // Check for register offset.
710185377Ssam    if (Memory.OffsetRegNum) return true;
711187831Ssam    // Immediate offset in range [-255, 255].
712185380Ssam    if (!Memory.OffsetImm) return true;
713185377Ssam    int64_t Val = Memory.OffsetImm->getValue();
714187831Ssam    return Val > -256 && Val < 256;
715185380Ssam  }
716185377Ssam  bool isAM3Offset() const {
717187831Ssam    if (Kind != k_Immediate && Kind != k_PostIndexRegister)
718185380Ssam      return false;
719187831Ssam    if (Kind == k_PostIndexRegister)
720185380Ssam      return PostIdxReg.ShiftTy == ARM_AM::no_shift;
721187831Ssam    // Immediate offset in range [-255, 255].
722185380Ssam    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
723187831Ssam    if (!CE) return false;
724185380Ssam    int64_t Val = CE->getValue();
725185377Ssam    // Special case, #-0 is INT32_MIN.
726187831Ssam    return (Val > -256 && Val < 256) || Val == INT32_MIN;
727185380Ssam  }
728187831Ssam  bool isAddrMode5() const {
729185380Ssam    if (!isMemory() || Memory.Alignment != 0) return false;
730187831Ssam    // Check for register offset.
731185380Ssam    if (Memory.OffsetRegNum) return false;
732187831Ssam    // Immediate offset in range [-1020, 1020] and a multiple of 4.
733185380Ssam    if (!Memory.OffsetImm) return true;
734187831Ssam    int64_t Val = Memory.OffsetImm->getValue();
735185380Ssam    return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) ||
736187831Ssam           Val == INT32_MIN;
737185380Ssam  }
738187831Ssam  bool isMemTBB() const {
739185380Ssam    if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative ||
740187831Ssam        Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0)
741185380Ssam      return false;
742187831Ssam    return true;
743185380Ssam  }
744187831Ssam  bool isMemTBH() const {
745185380Ssam    if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative ||
746187831Ssam        Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm != 1 ||
747185380Ssam        Memory.Alignment != 0 )
748187831Ssam      return false;
749185380Ssam    return true;
750187831Ssam  }
751185380Ssam  bool isMemRegOffset() const {
752185377Ssam    if (!isMemory() || !Memory.OffsetRegNum || Memory.Alignment != 0)
753185377Ssam      return false;
754185377Ssam    return true;
755185377Ssam  }
756185377Ssam  bool isT2MemRegOffset() const {
757185377Ssam    if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative ||
758187831Ssam        Memory.Alignment != 0)
759185380Ssam      return false;
760187831Ssam    // Only lsl #{0, 1, 2, 3} allowed.
761185380Ssam    if (Memory.ShiftType == ARM_AM::no_shift)
762187831Ssam      return true;
763185380Ssam    if (Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm > 3)
764187831Ssam      return false;
765185380Ssam    return true;
766187831Ssam  }
767185380Ssam  bool isMemThumbRR() const {
768187831Ssam    // Thumb reg+reg addressing is simple. Just two registers, a base and
769185380Ssam    // an offset. No shifts, negations or any other complicating factors.
770187831Ssam    if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative ||
771185380Ssam        Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0)
772187831Ssam      return false;
773185380Ssam    return isARMLowRegister(Memory.BaseRegNum) &&
774187831Ssam      (!Memory.OffsetRegNum || isARMLowRegister(Memory.OffsetRegNum));
775185380Ssam  }
776187831Ssam  bool isMemThumbRIs4() const {
777185380Ssam    if (!isMemory() || Memory.OffsetRegNum != 0 ||
778185377Ssam        !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
779185377Ssam      return false;
780185377Ssam    // Immediate offset, multiple of 4 in range [0, 124].
781185377Ssam    if (!Memory.OffsetImm) return true;
782185377Ssam    int64_t Val = Memory.OffsetImm->getValue();
783185377Ssam    return Val >= 0 && Val <= 124 && (Val % 4) == 0;
784187831Ssam  }
785185380Ssam  bool isMemThumbRIs2() const {
786187831Ssam    if (!isMemory() || Memory.OffsetRegNum != 0 ||
787185380Ssam        !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
788187831Ssam      return false;
789185380Ssam    // Immediate offset, multiple of 4 in range [0, 62].
790187831Ssam    if (!Memory.OffsetImm) return true;
791185380Ssam    int64_t Val = Memory.OffsetImm->getValue();
792185377Ssam    return Val >= 0 && Val <= 62 && (Val % 2) == 0;
793187831Ssam  }
794185380Ssam  bool isMemThumbRIs1() const {
795187831Ssam    if (!isMemory() || Memory.OffsetRegNum != 0 ||
796185380Ssam        !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
797187831Ssam      return false;
798185380Ssam    // Immediate offset in range [0, 31].
799187831Ssam    if (!Memory.OffsetImm) return true;
800185380Ssam    int64_t Val = Memory.OffsetImm->getValue();
801185377Ssam    return Val >= 0 && Val <= 31;
802187831Ssam  }
803185380Ssam  bool isMemThumbSPI() const {
804187831Ssam    if (!isMemory() || Memory.OffsetRegNum != 0 ||
805185380Ssam        Memory.BaseRegNum != ARM::SP || Memory.Alignment != 0)
806187831Ssam      return false;
807185380Ssam    // Immediate offset, multiple of 4 in range [0, 1020].
808187831Ssam    if (!Memory.OffsetImm) return true;
809185380Ssam    int64_t Val = Memory.OffsetImm->getValue();
810185377Ssam    return Val >= 0 && Val <= 1020 && (Val % 4) == 0;
811187831Ssam  }
812185380Ssam  bool isMemImm8s4Offset() const {
813187831Ssam    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
814185380Ssam      return false;
815187831Ssam    // Immediate offset a multiple of 4 in range [-1020, 1020].
816185380Ssam    if (!Memory.OffsetImm) return true;
817187831Ssam    int64_t Val = Memory.OffsetImm->getValue();
818185380Ssam    return Val >= -1020 && Val <= 1020 && (Val & 3) == 0;
819187831Ssam  }
820185380Ssam  bool isMemImm0_1020s4Offset() const {
821187831Ssam    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
822185380Ssam      return false;
823185377Ssam    // Immediate offset a multiple of 4 in range [0, 1020].
824187831Ssam    if (!Memory.OffsetImm) return true;
825185380Ssam    int64_t Val = Memory.OffsetImm->getValue();
826187831Ssam    return Val >= 0 && Val <= 1020 && (Val & 3) == 0;
827185380Ssam  }
828187831Ssam  bool isMemImm8Offset() const {
829185380Ssam    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
830185377Ssam      return false;
831187831Ssam    // Immediate offset in range [-255, 255].
832185380Ssam    if (!Memory.OffsetImm) return true;
833185377Ssam    int64_t Val = Memory.OffsetImm->getValue();
834185377Ssam    return (Val == INT32_MIN) || (Val > -256 && Val < 256);
835185377Ssam  }
836185377Ssam  bool isMemPosImm8Offset() const {
837187831Ssam    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
838185380Ssam      return false;
839187831Ssam    // Immediate offset in range [0, 255].
840185380Ssam    if (!Memory.OffsetImm) return true;
841187831Ssam    int64_t Val = Memory.OffsetImm->getValue();
842185380Ssam    return Val >= 0 && Val < 256;
843187831Ssam  }
844185380Ssam  bool isMemNegImm8Offset() const {
845185377Ssam    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
846185377Ssam      return false;
847185377Ssam    // Immediate offset in range [-255, -1].
848185377Ssam    if (!Memory.OffsetImm) return true;
849185377Ssam    int64_t Val = Memory.OffsetImm->getValue();
850185380Ssam    return Val > -256 && Val < 0;
851187831Ssam  }
852185380Ssam  bool isMemUImm12Offset() const {
853187831Ssam    // If we have an immediate that's not a constant, treat it as a label
854185380Ssam    // reference needing a fixup. If it is a constant, it's something else
855185377Ssam    // and we reject it.
856187831Ssam    if (Kind == k_Immediate && !isa<MCConstantExpr>(getImm()))
857185380Ssam      return true;
858187831Ssam
859185380Ssam    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
860187831Ssam      return false;
861185380Ssam    // Immediate offset in range [0, 4095].
862185377Ssam    if (!Memory.OffsetImm) return true;
863187831Ssam    int64_t Val = Memory.OffsetImm->getValue();
864185380Ssam    return (Val >= 0 && Val < 4096);
865187831Ssam  }
866185380Ssam  bool isMemImm12Offset() const {
867185377Ssam    // If we have an immediate that's not a constant, treat it as a label
868187831Ssam    // reference needing a fixup. If it is a constant, it's something else
869185380Ssam    // and we reject it.
870185377Ssam    if (Kind == k_Immediate && !isa<MCConstantExpr>(getImm()))
871187831Ssam      return true;
872185380Ssam
873185377Ssam    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
874187831Ssam      return false;
875185380Ssam    // Immediate offset in range [-4095, 4095].
876185377Ssam    if (!Memory.OffsetImm) return true;
877187831Ssam    int64_t Val = Memory.OffsetImm->getValue();
878185380Ssam    return (Val > -4096 && Val < 4096) || (Val == INT32_MIN);
879187831Ssam  }
880185380Ssam  bool isPostIdxImm8() const {
881185377Ssam    if (Kind != k_Immediate)
882187831Ssam      return false;
883185380Ssam    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
884185377Ssam    if (!CE) return false;
885185377Ssam    int64_t Val = CE->getValue();
886185380Ssam    return (Val > -256 && Val < 256) || (Val == INT32_MIN);
887185380Ssam  }
888185377Ssam  bool isPostIdxImm8s4() const {
889187831Ssam    if (Kind != k_Immediate)
890185380Ssam      return false;
891187831Ssam    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
892185380Ssam    if (!CE) return false;
893187831Ssam    int64_t Val = CE->getValue();
894185380Ssam    return ((Val & 3) == 0 && Val >= -1020 && Val <= 1020) ||
895187831Ssam      (Val == INT32_MIN);
896185380Ssam  }
897187831Ssam
898185380Ssam  bool isMSRMask() const { return Kind == k_MSRMask; }
899187831Ssam  bool isProcIFlags() const { return Kind == k_ProcIFlags; }
900185380Ssam
901187831Ssam  bool isVectorIndex8() const {
902185380Ssam    if (Kind != k_VectorIndex) return false;
903187831Ssam    return VectorIndex.Val < 8;
904185380Ssam  }
905187831Ssam  bool isVectorIndex16() const {
906185380Ssam    if (Kind != k_VectorIndex) return false;
907187831Ssam    return VectorIndex.Val < 4;
908185380Ssam  }
909187831Ssam  bool isVectorIndex32() const {
910185380Ssam    if (Kind != k_VectorIndex) return false;
911187831Ssam    return VectorIndex.Val < 2;
912185380Ssam  }
913185377Ssam
914185377Ssam
915185377Ssam
916185377Ssam  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
917185377Ssam    // Add as immediates when possible.  Null MCExpr = 0.
918185377Ssam    if (Expr == 0)
919187831Ssam      Inst.addOperand(MCOperand::CreateImm(0));
920185380Ssam    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
921187831Ssam      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
922185380Ssam    else
923187831Ssam      Inst.addOperand(MCOperand::CreateExpr(Expr));
924185380Ssam  }
925187831Ssam
926185380Ssam  void addCondCodeOperands(MCInst &Inst, unsigned N) const {
927185377Ssam    assert(N == 2 && "Invalid number of operands!");
928187831Ssam    Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode())));
929185380Ssam    unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR;
930187831Ssam    Inst.addOperand(MCOperand::CreateReg(RegNum));
931185380Ssam  }
932187831Ssam
933185380Ssam  void addCoprocNumOperands(MCInst &Inst, unsigned N) const {
934187831Ssam    assert(N == 1 && "Invalid number of operands!");
935185380Ssam    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
936187831Ssam  }
937185380Ssam
938185377Ssam  void addCoprocRegOperands(MCInst &Inst, unsigned N) const {
939187831Ssam    assert(N == 1 && "Invalid number of operands!");
940185380Ssam    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
941187831Ssam  }
942185380Ssam
943187831Ssam  void addCoprocOptionOperands(MCInst &Inst, unsigned N) const {
944185380Ssam    assert(N == 1 && "Invalid number of operands!");
945187831Ssam    Inst.addOperand(MCOperand::CreateImm(CoprocOption.Val));
946185380Ssam  }
947185377Ssam
948187831Ssam  void addITMaskOperands(MCInst &Inst, unsigned N) const {
949185380Ssam    assert(N == 1 && "Invalid number of operands!");
950185377Ssam    Inst.addOperand(MCOperand::CreateImm(ITMask.Mask));
951187831Ssam  }
952185380Ssam
953185377Ssam  void addITCondCodeOperands(MCInst &Inst, unsigned N) const {
954187831Ssam    assert(N == 1 && "Invalid number of operands!");
955185380Ssam    Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode())));
956187831Ssam  }
957185380Ssam
958187831Ssam  void addCCOutOperands(MCInst &Inst, unsigned N) const {
959185380Ssam    assert(N == 1 && "Invalid number of operands!");
960185377Ssam    Inst.addOperand(MCOperand::CreateReg(getReg()));
961187831Ssam  }
962185380Ssam
963185377Ssam  void addRegOperands(MCInst &Inst, unsigned N) const {
964185377Ssam    assert(N == 1 && "Invalid number of operands!");
965185377Ssam    Inst.addOperand(MCOperand::CreateReg(getReg()));
966185377Ssam  }
967187831Ssam
968185380Ssam  void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const {
969187831Ssam    assert(N == 3 && "Invalid number of operands!");
970185380Ssam    assert(isRegShiftedReg() && "addRegShiftedRegOperands() on non RegShiftedReg!");
971187831Ssam    Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.SrcReg));
972185380Ssam    Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.ShiftReg));
973187831Ssam    Inst.addOperand(MCOperand::CreateImm(
974185380Ssam      ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm)));
975187831Ssam  }
976185380Ssam
977187831Ssam  void addRegShiftedImmOperands(MCInst &Inst, unsigned N) const {
978185380Ssam    assert(N == 2 && "Invalid number of operands!");
979187831Ssam    assert(isRegShiftedImm() && "addRegShiftedImmOperands() on non RegShiftedImm!");
980185380Ssam    Inst.addOperand(MCOperand::CreateReg(RegShiftedImm.SrcReg));
981187831Ssam    Inst.addOperand(MCOperand::CreateImm(
982185380Ssam      ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, RegShiftedImm.ShiftImm)));
983187831Ssam  }
984185380Ssam
985187831Ssam  void addShifterImmOperands(MCInst &Inst, unsigned N) const {
986185380Ssam    assert(N == 1 && "Invalid number of operands!");
987185377Ssam    Inst.addOperand(MCOperand::CreateImm((ShifterImm.isASR << 5) |
988185377Ssam                                         ShifterImm.Imm));
989185377Ssam  }
990185377Ssam
991185377Ssam  void addRegListOperands(MCInst &Inst, unsigned N) const {
992185377Ssam    assert(N == 1 && "Invalid number of operands!");
993187831Ssam    const SmallVectorImpl<unsigned> &RegList = getRegList();
994185380Ssam    for (SmallVectorImpl<unsigned>::const_iterator
995187831Ssam           I = RegList.begin(), E = RegList.end(); I != E; ++I)
996185380Ssam      Inst.addOperand(MCOperand::CreateReg(*I));
997187831Ssam  }
998185380Ssam
999187831Ssam  void addDPRRegListOperands(MCInst &Inst, unsigned N) const {
1000185380Ssam    addRegListOperands(Inst, N);
1001187831Ssam  }
1002185380Ssam
1003185377Ssam  void addSPRRegListOperands(MCInst &Inst, unsigned N) const {
1004185377Ssam    addRegListOperands(Inst, N);
1005185377Ssam  }
1006185380Ssam
1007185377Ssam  void addRotImmOperands(MCInst &Inst, unsigned N) const {
1008185380Ssam    assert(N == 1 && "Invalid number of operands!");
1009185380Ssam    // Encoded as val>>3. The printer handles display as 8, 16, 24.
1010185380Ssam    Inst.addOperand(MCOperand::CreateImm(RotImm.Imm >> 3));
1011185380Ssam  }
1012185380Ssam
1013185380Ssam  void addBitfieldOperands(MCInst &Inst, unsigned N) const {
1014185380Ssam    assert(N == 1 && "Invalid number of operands!");
1015185380Ssam    // Munge the lsb/width into a bitfield mask.
1016185380Ssam    unsigned lsb = Bitfield.LSB;
1017185380Ssam    unsigned width = Bitfield.Width;
1018185380Ssam    // Make a 32-bit mask w/ the referenced bits clear and all other bits set.
1019185380Ssam    uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >>
1020185380Ssam                      (32 - (lsb + width)));
1021185380Ssam    Inst.addOperand(MCOperand::CreateImm(Mask));
1022185377Ssam  }
1023185377Ssam
1024185377Ssam  void addImmOperands(MCInst &Inst, unsigned N) const {
1025185377Ssam    assert(N == 1 && "Invalid number of operands!");
1026185380Ssam    addExpr(Inst, getImm());
1027185380Ssam  }
1028185380Ssam
1029187831Ssam  void addFPImmOperands(MCInst &Inst, unsigned N) const {
1030187831Ssam    assert(N == 1 && "Invalid number of operands!");
1031187831Ssam    Inst.addOperand(MCOperand::CreateImm(getFPImm()));
1032185380Ssam  }
1033185380Ssam
1034185380Ssam  void addImm8s4Operands(MCInst &Inst, unsigned N) const {
1035185380Ssam    assert(N == 1 && "Invalid number of operands!");
1036185380Ssam    // FIXME: We really want to scale the value here, but the LDRD/STRD
1037185380Ssam    // instruction don't encode operands that way yet.
1038185380Ssam    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1039185380Ssam    Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
1040185380Ssam  }
1041185380Ssam
1042185380Ssam  void addImm0_1020s4Operands(MCInst &Inst, unsigned N) const {
1043185380Ssam    assert(N == 1 && "Invalid number of operands!");
1044185380Ssam    // The immediate is scaled by four in the encoding and is stored
1045185380Ssam    // in the MCInst as such. Lop off the low two bits here.
1046185380Ssam    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1047185380Ssam    Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4));
1048185380Ssam  }
1049185380Ssam
1050185380Ssam  void addImm0_508s4Operands(MCInst &Inst, unsigned N) const {
1051185380Ssam    assert(N == 1 && "Invalid number of operands!");
1052185380Ssam    // The immediate is scaled by four in the encoding and is stored
1053185377Ssam    // in the MCInst as such. Lop off the low two bits here.
1054185380Ssam    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1055185380Ssam    Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4));
1056185380Ssam  }
1057185380Ssam
1058185377Ssam  void addImm0_255Operands(MCInst &Inst, unsigned N) const {
1059185380Ssam    assert(N == 1 && "Invalid number of operands!");
1060185380Ssam    addExpr(Inst, getImm());
1061185380Ssam  }
1062185380Ssam
1063185377Ssam  void addImm0_7Operands(MCInst &Inst, unsigned N) const {
1064185380Ssam    assert(N == 1 && "Invalid number of operands!");
1065185380Ssam    addExpr(Inst, getImm());
1066185380Ssam  }
1067185380Ssam
1068185377Ssam  void addImm0_15Operands(MCInst &Inst, unsigned N) const {
1069185380Ssam    assert(N == 1 && "Invalid number of operands!");
1070185380Ssam    addExpr(Inst, getImm());
1071185380Ssam  }
1072185380Ssam
1073185377Ssam  void addImm0_31Operands(MCInst &Inst, unsigned N) const {
1074185380Ssam    assert(N == 1 && "Invalid number of operands!");
1075185380Ssam    addExpr(Inst, getImm());
1076185380Ssam  }
1077185380Ssam
1078185377Ssam  void addImm1_16Operands(MCInst &Inst, unsigned N) const {
1079185380Ssam    assert(N == 1 && "Invalid number of operands!");
1080185380Ssam    // The constant encodes as the immediate-1, and we store in the instruction
1081185380Ssam    // the bits as encoded, so subtract off one here.
1082185380Ssam    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1083185380Ssam    Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1));
1084185380Ssam  }
1085185380Ssam
1086185377Ssam  void addImm1_32Operands(MCInst &Inst, unsigned N) const {
1087185380Ssam    assert(N == 1 && "Invalid number of operands!");
1088185380Ssam    // The constant encodes as the immediate-1, and we store in the instruction
1089185380Ssam    // the bits as encoded, so subtract off one here.
1090185380Ssam    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1091185380Ssam    Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1));
1092185377Ssam  }
1093185380Ssam
1094185380Ssam  void addImm0_65535Operands(MCInst &Inst, unsigned N) const {
1095185380Ssam    assert(N == 1 && "Invalid number of operands!");
1096185380Ssam    addExpr(Inst, getImm());
1097185380Ssam  }
1098185380Ssam
1099185380Ssam  void addImm0_65535ExprOperands(MCInst &Inst, unsigned N) const {
1100185377Ssam    assert(N == 1 && "Invalid number of operands!");
1101185380Ssam    addExpr(Inst, getImm());
1102185380Ssam  }
1103185380Ssam
1104185380Ssam  void addImm24bitOperands(MCInst &Inst, unsigned N) const {
1105185380Ssam    assert(N == 1 && "Invalid number of operands!");
1106185380Ssam    addExpr(Inst, getImm());
1107185380Ssam  }
1108185377Ssam
1109185380Ssam  void addImmThumbSROperands(MCInst &Inst, unsigned N) const {
1110185380Ssam    assert(N == 1 && "Invalid number of operands!");
1111185380Ssam    // The constant encodes as the immediate, except for 32, which encodes as
1112185380Ssam    // zero.
1113185380Ssam    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1114185380Ssam    unsigned Imm = CE->getValue();
1115185380Ssam    Inst.addOperand(MCOperand::CreateImm((Imm == 32 ? 0 : Imm)));
1116185377Ssam  }
1117185380Ssam
1118185380Ssam  void addPKHLSLImmOperands(MCInst &Inst, unsigned N) const {
1119185380Ssam    assert(N == 1 && "Invalid number of operands!");
1120185380Ssam    addExpr(Inst, getImm());
1121185380Ssam  }
1122185380Ssam
1123185380Ssam  void addPKHASRImmOperands(MCInst &Inst, unsigned N) const {
1124185377Ssam    assert(N == 1 && "Invalid number of operands!");
1125185380Ssam    // An ASR value of 32 encodes as 0, so that's how we want to add it to
1126185380Ssam    // the instruction as well.
1127185380Ssam    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1128185380Ssam    int Val = CE->getValue();
1129185380Ssam    Inst.addOperand(MCOperand::CreateImm(Val == 32 ? 0 : Val));
1130185380Ssam  }
1131185380Ssam
1132185377Ssam  void addARMSOImmOperands(MCInst &Inst, unsigned N) const {
1133185380Ssam    assert(N == 1 && "Invalid number of operands!");
1134185380Ssam    addExpr(Inst, getImm());
1135185380Ssam  }
1136185380Ssam
1137185380Ssam  void addT2SOImmOperands(MCInst &Inst, unsigned N) const {
1138185380Ssam    assert(N == 1 && "Invalid number of operands!");
1139185380Ssam    addExpr(Inst, getImm());
1140185377Ssam  }
1141185380Ssam
1142185380Ssam  void addSetEndImmOperands(MCInst &Inst, unsigned N) const {
1143185380Ssam    assert(N == 1 && "Invalid number of operands!");
1144185380Ssam    addExpr(Inst, getImm());
1145185380Ssam  }
1146185380Ssam
1147185380Ssam  void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const {
1148185377Ssam    assert(N == 1 && "Invalid number of operands!");
1149185380Ssam    Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt())));
1150185380Ssam  }
1151185380Ssam
1152185380Ssam  void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const {
1153185380Ssam    assert(N == 1 && "Invalid number of operands!");
1154185380Ssam    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1155185377Ssam  }
1156185380Ssam
1157185380Ssam  void addAlignedMemoryOperands(MCInst &Inst, unsigned N) const {
1158185380Ssam    assert(N == 2 && "Invalid number of operands!");
1159185380Ssam    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1160185380Ssam    Inst.addOperand(MCOperand::CreateImm(Memory.Alignment));
1161185377Ssam  }
1162185380Ssam
1163185380Ssam  void addAddrMode2Operands(MCInst &Inst, unsigned N) const {
1164185380Ssam    assert(N == 3 && "Invalid number of operands!");
1165185380Ssam    int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1166185380Ssam    if (!Memory.OffsetRegNum) {
1167185380Ssam      ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
1168185380Ssam      // Special case for #-0
1169185380Ssam      if (Val == INT32_MIN) Val = 0;
1170185380Ssam      if (Val < 0) Val = -Val;
1171185380Ssam      Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
1172185380Ssam    } else {
1173185380Ssam      // For register offset, we encode the shift type and negation flag
1174185380Ssam      // here.
1175185380Ssam      Val = ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add,
1176185377Ssam                              Memory.ShiftImm, Memory.ShiftType);
1177185380Ssam    }
1178185380Ssam    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1179185380Ssam    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
1180185380Ssam    Inst.addOperand(MCOperand::CreateImm(Val));
1181185380Ssam  }
1182185380Ssam
1183185380Ssam  void addAM2OffsetImmOperands(MCInst &Inst, unsigned N) const {
1184185380Ssam    assert(N == 2 && "Invalid number of operands!");
1185185377Ssam    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1186185380Ssam    assert(CE && "non-constant AM2OffsetImm operand!");
1187185380Ssam    int32_t Val = CE->getValue();
1188185380Ssam    ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
1189185380Ssam    // Special case for #-0
1190185380Ssam    if (Val == INT32_MIN) Val = 0;
1191185380Ssam    if (Val < 0) Val = -Val;
1192185380Ssam    Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
1193185380Ssam    Inst.addOperand(MCOperand::CreateReg(0));
1194185380Ssam    Inst.addOperand(MCOperand::CreateImm(Val));
1195185377Ssam  }
1196185380Ssam
1197185380Ssam  void addAddrMode3Operands(MCInst &Inst, unsigned N) const {
1198185380Ssam    assert(N == 3 && "Invalid number of operands!");
1199185380Ssam    int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1200185380Ssam    if (!Memory.OffsetRegNum) {
1201185380Ssam      ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
1202185377Ssam      // Special case for #-0
1203185380Ssam      if (Val == INT32_MIN) Val = 0;
1204185380Ssam      if (Val < 0) Val = -Val;
1205185380Ssam      Val = ARM_AM::getAM3Opc(AddSub, Val);
1206185380Ssam    } else {
1207185380Ssam      // For register offset, we encode the shift type and negation flag
1208187831Ssam      // here.
1209185380Ssam      Val = ARM_AM::getAM3Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 0);
1210185380Ssam    }
1211185380Ssam    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1212185380Ssam    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
1213185380Ssam    Inst.addOperand(MCOperand::CreateImm(Val));
1214185377Ssam  }
1215185380Ssam
1216185380Ssam  void addAM3OffsetOperands(MCInst &Inst, unsigned N) const {
1217185380Ssam    assert(N == 2 && "Invalid number of operands!");
1218185380Ssam    if (Kind == k_PostIndexRegister) {
1219185380Ssam      int32_t Val =
1220185380Ssam        ARM_AM::getAM3Opc(PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub, 0);
1221185377Ssam      Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
1222185377Ssam      Inst.addOperand(MCOperand::CreateImm(Val));
1223185380Ssam      return;
1224185380Ssam    }
1225185380Ssam
1226185380Ssam    // Constant offset.
1227185380Ssam    const MCConstantExpr *CE = static_cast<const MCConstantExpr*>(getImm());
1228185380Ssam    int32_t Val = CE->getValue();
1229185380Ssam    ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
1230185377Ssam    // Special case for #-0
1231185377Ssam    if (Val == INT32_MIN) Val = 0;
1232185380Ssam    if (Val < 0) Val = -Val;
1233185380Ssam    Val = ARM_AM::getAM3Opc(AddSub, Val);
1234185380Ssam    Inst.addOperand(MCOperand::CreateReg(0));
1235185380Ssam    Inst.addOperand(MCOperand::CreateImm(Val));
1236185380Ssam  }
1237185380Ssam
1238185380Ssam  void addAddrMode5Operands(MCInst &Inst, unsigned N) const {
1239185377Ssam    assert(N == 2 && "Invalid number of operands!");
1240185377Ssam    // The lower two bits are always zero and as such are not encoded.
1241185380Ssam    int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0;
1242185380Ssam    ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
1243185380Ssam    // Special case for #-0
1244185380Ssam    if (Val == INT32_MIN) Val = 0;
1245185380Ssam    if (Val < 0) Val = -Val;
1246185380Ssam    Val = ARM_AM::getAM5Opc(AddSub, Val);
1247185377Ssam    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1248185377Ssam    Inst.addOperand(MCOperand::CreateImm(Val));
1249185380Ssam  }
1250185380Ssam
1251185380Ssam  void addMemImm8s4OffsetOperands(MCInst &Inst, unsigned N) const {
1252185380Ssam    assert(N == 2 && "Invalid number of operands!");
1253185380Ssam    int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1254185380Ssam    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1255185380Ssam    Inst.addOperand(MCOperand::CreateImm(Val));
1256185377Ssam  }
1257185377Ssam
1258185380Ssam  void addMemImm0_1020s4OffsetOperands(MCInst &Inst, unsigned N) const {
1259185380Ssam    assert(N == 2 && "Invalid number of operands!");
1260185380Ssam    // The lower two bits are always zero and as such are not encoded.
1261185380Ssam    int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0;
1262185380Ssam    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1263185380Ssam    Inst.addOperand(MCOperand::CreateImm(Val));
1264185380Ssam  }
1265185380Ssam
1266185380Ssam  void addMemImm8OffsetOperands(MCInst &Inst, unsigned N) const {
1267185380Ssam    assert(N == 2 && "Invalid number of operands!");
1268185377Ssam    int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1269185377Ssam    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1270185380Ssam    Inst.addOperand(MCOperand::CreateImm(Val));
1271185380Ssam  }
1272185380Ssam
1273185380Ssam  void addMemPosImm8OffsetOperands(MCInst &Inst, unsigned N) const {
1274185380Ssam    addMemImm8OffsetOperands(Inst, N);
1275185380Ssam  }
1276185380Ssam
1277185380Ssam  void addMemNegImm8OffsetOperands(MCInst &Inst, unsigned N) const {
1278185380Ssam    addMemImm8OffsetOperands(Inst, N);
1279185380Ssam  }
1280185380Ssam
1281185380Ssam  void addMemUImm12OffsetOperands(MCInst &Inst, unsigned N) const {
1282185377Ssam    assert(N == 2 && "Invalid number of operands!");
1283185377Ssam    // If this is an immediate, it's a label reference.
1284185380Ssam    if (Kind == k_Immediate) {
1285185380Ssam      addExpr(Inst, getImm());
1286185380Ssam      Inst.addOperand(MCOperand::CreateImm(0));
1287185380Ssam      return;
1288185380Ssam    }
1289185380Ssam
1290185380Ssam    // Otherwise, it's a normal memory reg+offset.
1291185380Ssam    int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1292185380Ssam    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1293185380Ssam    Inst.addOperand(MCOperand::CreateImm(Val));
1294185380Ssam  }
1295185380Ssam
1296185380Ssam  void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const {
1297185380Ssam    assert(N == 2 && "Invalid number of operands!");
1298185377Ssam    // If this is an immediate, it's a label reference.
1299185377Ssam    if (Kind == k_Immediate) {
1300185380Ssam      addExpr(Inst, getImm());
1301185380Ssam      Inst.addOperand(MCOperand::CreateImm(0));
1302185380Ssam      return;
1303185380Ssam    }
1304185380Ssam
1305185377Ssam    // Otherwise, it's a normal memory reg+offset.
1306185380Ssam    int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1307185380Ssam    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1308185380Ssam    Inst.addOperand(MCOperand::CreateImm(Val));
1309185380Ssam  }
1310185380Ssam
1311185380Ssam  void addMemTBBOperands(MCInst &Inst, unsigned N) const {
1312185380Ssam    assert(N == 2 && "Invalid number of operands!");
1313185380Ssam    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1314185377Ssam    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
1315185380Ssam  }
1316185380Ssam
1317185380Ssam  void addMemTBHOperands(MCInst &Inst, unsigned N) const {
1318185380Ssam    assert(N == 2 && "Invalid number of operands!");
1319185380Ssam    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1320185380Ssam    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
1321185380Ssam  }
1322185380Ssam
1323185377Ssam  void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const {
1324185380Ssam    assert(N == 3 && "Invalid number of operands!");
1325185380Ssam    unsigned Val = ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add,
1326185380Ssam                                     Memory.ShiftImm, Memory.ShiftType);
1327185380Ssam    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1328185380Ssam    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
1329185380Ssam    Inst.addOperand(MCOperand::CreateImm(Val));
1330185380Ssam  }
1331185380Ssam
1332185377Ssam  void addT2MemRegOffsetOperands(MCInst &Inst, unsigned N) const {
1333185380Ssam    assert(N == 3 && "Invalid number of operands!");
1334185380Ssam    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1335185380Ssam    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
1336185380Ssam    Inst.addOperand(MCOperand::CreateImm(Memory.ShiftImm));
1337185380Ssam  }
1338185380Ssam
1339185377Ssam  void addMemThumbRROperands(MCInst &Inst, unsigned N) const {
1340185380Ssam    assert(N == 2 && "Invalid number of operands!");
1341185380Ssam    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1342185380Ssam    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
1343185380Ssam  }
1344185380Ssam
1345185380Ssam  void addMemThumbRIs4Operands(MCInst &Inst, unsigned N) const {
1346185380Ssam    assert(N == 2 && "Invalid number of operands!");
1347185380Ssam    int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0;
1348185380Ssam    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1349185377Ssam    Inst.addOperand(MCOperand::CreateImm(Val));
1350185380Ssam  }
1351185380Ssam
1352185380Ssam  void addMemThumbRIs2Operands(MCInst &Inst, unsigned N) const {
1353185380Ssam    assert(N == 2 && "Invalid number of operands!");
1354185380Ssam    int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 2) : 0;
1355185380Ssam    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1356185380Ssam    Inst.addOperand(MCOperand::CreateImm(Val));
1357185380Ssam  }
1358185380Ssam
1359185380Ssam  void addMemThumbRIs1Operands(MCInst &Inst, unsigned N) const {
1360185377Ssam    assert(N == 2 && "Invalid number of operands!");
1361185380Ssam    int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue()) : 0;
1362185380Ssam    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1363185380Ssam    Inst.addOperand(MCOperand::CreateImm(Val));
1364185380Ssam  }
1365185380Ssam
1366185380Ssam  void addMemThumbSPIOperands(MCInst &Inst, unsigned N) const {
1367185377Ssam    assert(N == 2 && "Invalid number of operands!");
1368185380Ssam    int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0;
1369185380Ssam    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1370185380Ssam    Inst.addOperand(MCOperand::CreateImm(Val));
1371185380Ssam  }
1372185380Ssam
1373185380Ssam  void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const {
1374185377Ssam    assert(N == 1 && "Invalid number of operands!");
1375185380Ssam    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1376185380Ssam    assert(CE && "non-constant post-idx-imm8 operand!");
1377185380Ssam    int Imm = CE->getValue();
1378185380Ssam    bool isAdd = Imm >= 0;
1379185380Ssam    if (Imm == INT32_MIN) Imm = 0;
1380185380Ssam    Imm = (Imm < 0 ? -Imm : Imm) | (int)isAdd << 8;
1381185380Ssam    Inst.addOperand(MCOperand::CreateImm(Imm));
1382185380Ssam  }
1383185380Ssam
1384185380Ssam  void addPostIdxImm8s4Operands(MCInst &Inst, unsigned N) const {
1385185380Ssam    assert(N == 1 && "Invalid number of operands!");
1386185380Ssam    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1387185380Ssam    assert(CE && "non-constant post-idx-imm8s4 operand!");
1388185380Ssam    int Imm = CE->getValue();
1389185380Ssam    bool isAdd = Imm >= 0;
1390185380Ssam    if (Imm == INT32_MIN) Imm = 0;
1391185380Ssam    // Immediate is scaled by 4.
1392185380Ssam    Imm = ((Imm < 0 ? -Imm : Imm) / 4) | (int)isAdd << 8;
1393185380Ssam    Inst.addOperand(MCOperand::CreateImm(Imm));
1394185380Ssam  }
1395185380Ssam
1396185380Ssam  void addPostIdxRegOperands(MCInst &Inst, unsigned N) const {
1397185380Ssam    assert(N == 2 && "Invalid number of operands!");
1398185380Ssam    Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
1399185380Ssam    Inst.addOperand(MCOperand::CreateImm(PostIdxReg.isAdd));
1400185380Ssam  }
1401185380Ssam
1402185380Ssam  void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const {
1403185380Ssam    assert(N == 2 && "Invalid number of operands!");
1404185380Ssam    Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
1405185377Ssam    // The sign, shift type, and shift amount are encoded in a single operand
1406185380Ssam    // using the AM2 encoding helpers.
1407185380Ssam    ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub;
1408185380Ssam    unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm,
1409185380Ssam                                     PostIdxReg.ShiftTy);
1410185380Ssam    Inst.addOperand(MCOperand::CreateImm(Imm));
1411185380Ssam  }
1412185380Ssam
1413185380Ssam  void addMSRMaskOperands(MCInst &Inst, unsigned N) const {
1414185380Ssam    assert(N == 1 && "Invalid number of operands!");
1415185380Ssam    Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask())));
1416185380Ssam  }
1417185380Ssam
1418185380Ssam  void addProcIFlagsOperands(MCInst &Inst, unsigned N) const {
1419185380Ssam    assert(N == 1 && "Invalid number of operands!");
1420185380Ssam    Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags())));
1421185380Ssam  }
1422185380Ssam
1423185380Ssam  void addVectorIndex8Operands(MCInst &Inst, unsigned N) const {
1424185380Ssam    assert(N == 1 && "Invalid number of operands!");
1425185380Ssam    Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1426185380Ssam  }
1427185380Ssam
1428185380Ssam  void addVectorIndex16Operands(MCInst &Inst, unsigned N) const {
1429185380Ssam    assert(N == 1 && "Invalid number of operands!");
1430185377Ssam    Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1431185380Ssam  }
1432185380Ssam
1433185380Ssam  void addVectorIndex32Operands(MCInst &Inst, unsigned N) const {
1434185380Ssam    assert(N == 1 && "Invalid number of operands!");
1435185380Ssam    Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1436185380Ssam  }
1437185380Ssam
1438185380Ssam  virtual void print(raw_ostream &OS) const;
1439185380Ssam
1440185380Ssam  static ARMOperand *CreateITMask(unsigned Mask, SMLoc S) {
1441185380Ssam    ARMOperand *Op = new ARMOperand(k_ITCondMask);
1442185380Ssam    Op->ITMask.Mask = Mask;
1443185380Ssam    Op->StartLoc = S;
1444185380Ssam    Op->EndLoc = S;
1445185380Ssam    return Op;
1446185380Ssam  }
1447185380Ssam
1448185380Ssam  static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) {
1449185380Ssam    ARMOperand *Op = new ARMOperand(k_CondCode);
1450185380Ssam    Op->CC.Val = CC;
1451185380Ssam    Op->StartLoc = S;
1452185380Ssam    Op->EndLoc = S;
1453185380Ssam    return Op;
1454185380Ssam  }
1455185380Ssam
1456185380Ssam  static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) {
1457185380Ssam    ARMOperand *Op = new ARMOperand(k_CoprocNum);
1458185380Ssam    Op->Cop.Val = CopVal;
1459185377Ssam    Op->StartLoc = S;
1460185380Ssam    Op->EndLoc = S;
1461185380Ssam    return Op;
1462185380Ssam  }
1463185380Ssam
1464185380Ssam  static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) {
1465185380Ssam    ARMOperand *Op = new ARMOperand(k_CoprocReg);
1466185380Ssam    Op->Cop.Val = CopVal;
1467185380Ssam    Op->StartLoc = S;
1468185380Ssam    Op->EndLoc = S;
1469185380Ssam    return Op;
1470185380Ssam  }
1471185380Ssam
1472185380Ssam  static ARMOperand *CreateCoprocOption(unsigned Val, SMLoc S, SMLoc E) {
1473185380Ssam    ARMOperand *Op = new ARMOperand(k_CoprocOption);
1474185380Ssam    Op->Cop.Val = Val;
1475185380Ssam    Op->StartLoc = S;
1476185380Ssam    Op->EndLoc = E;
1477185380Ssam    return Op;
1478185380Ssam  }
1479185380Ssam
1480185380Ssam  static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) {
1481185380Ssam    ARMOperand *Op = new ARMOperand(k_CCOut);
1482185380Ssam    Op->Reg.RegNum = RegNum;
1483185380Ssam    Op->StartLoc = S;
1484185380Ssam    Op->EndLoc = S;
1485185380Ssam    return Op;
1486185380Ssam  }
1487185380Ssam
1488185377Ssam  static ARMOperand *CreateToken(StringRef Str, SMLoc S) {
1489185380Ssam    ARMOperand *Op = new ARMOperand(k_Token);
1490185380Ssam    Op->Tok.Data = Str.data();
1491185380Ssam    Op->Tok.Length = Str.size();
1492185380Ssam    Op->StartLoc = S;
1493187831Ssam    Op->EndLoc = S;
1494185380Ssam    return Op;
1495185380Ssam  }
1496185380Ssam
1497185380Ssam  static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
1498185380Ssam    ARMOperand *Op = new ARMOperand(k_Register);
1499185380Ssam    Op->Reg.RegNum = RegNum;
1500185380Ssam    Op->StartLoc = S;
1501185380Ssam    Op->EndLoc = E;
1502185380Ssam    return Op;
1503185380Ssam  }
1504185380Ssam
1505185380Ssam  static ARMOperand *CreateShiftedRegister(ARM_AM::ShiftOpc ShTy,
1506185380Ssam                                           unsigned SrcReg,
1507185380Ssam                                           unsigned ShiftReg,
1508185380Ssam                                           unsigned ShiftImm,
1509185380Ssam                                           SMLoc S, SMLoc E) {
1510185380Ssam    ARMOperand *Op = new ARMOperand(k_ShiftedRegister);
1511185380Ssam    Op->RegShiftedReg.ShiftTy = ShTy;
1512185380Ssam    Op->RegShiftedReg.SrcReg = SrcReg;
1513185380Ssam    Op->RegShiftedReg.ShiftReg = ShiftReg;
1514185380Ssam    Op->RegShiftedReg.ShiftImm = ShiftImm;
1515185380Ssam    Op->StartLoc = S;
1516185377Ssam    Op->EndLoc = E;
1517185380Ssam    return Op;
1518185380Ssam  }
1519185380Ssam
1520185380Ssam  static ARMOperand *CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy,
1521187831Ssam                                            unsigned SrcReg,
1522185380Ssam                                            unsigned ShiftImm,
1523185380Ssam                                            SMLoc S, SMLoc E) {
1524185380Ssam    ARMOperand *Op = new ARMOperand(k_ShiftedImmediate);
1525185380Ssam    Op->RegShiftedImm.ShiftTy = ShTy;
1526185380Ssam    Op->RegShiftedImm.SrcReg = SrcReg;
1527185380Ssam    Op->RegShiftedImm.ShiftImm = ShiftImm;
1528185380Ssam    Op->StartLoc = S;
1529185380Ssam    Op->EndLoc = E;
1530185380Ssam    return Op;
1531185380Ssam  }
1532185380Ssam
1533185380Ssam  static ARMOperand *CreateShifterImm(bool isASR, unsigned Imm,
1534185380Ssam                                   SMLoc S, SMLoc E) {
1535185380Ssam    ARMOperand *Op = new ARMOperand(k_ShifterImmediate);
1536185380Ssam    Op->ShifterImm.isASR = isASR;
1537185380Ssam    Op->ShifterImm.Imm = Imm;
1538185380Ssam    Op->StartLoc = S;
1539185380Ssam    Op->EndLoc = E;
1540185380Ssam    return Op;
1541185380Ssam  }
1542185380Ssam
1543185380Ssam  static ARMOperand *CreateRotImm(unsigned Imm, SMLoc S, SMLoc E) {
1544185380Ssam    ARMOperand *Op = new ARMOperand(k_RotateImmediate);
1545185380Ssam    Op->RotImm.Imm = Imm;
1546185377Ssam    Op->StartLoc = S;
1547185380Ssam    Op->EndLoc = E;
1548185380Ssam    return Op;
1549185380Ssam  }
1550185380Ssam
1551185380Ssam  static ARMOperand *CreateBitfield(unsigned LSB, unsigned Width,
1552185380Ssam                                    SMLoc S, SMLoc E) {
1553185380Ssam    ARMOperand *Op = new ARMOperand(k_BitfieldDescriptor);
1554185380Ssam    Op->Bitfield.LSB = LSB;
1555185380Ssam    Op->Bitfield.Width = Width;
1556185380Ssam    Op->StartLoc = S;
1557185380Ssam    Op->EndLoc = E;
1558185380Ssam    return Op;
1559185380Ssam  }
1560185380Ssam
1561185380Ssam  static ARMOperand *
1562185380Ssam  CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs,
1563185380Ssam                SMLoc StartLoc, SMLoc EndLoc) {
1564185380Ssam    KindTy Kind = k_RegisterList;
1565185380Ssam
1566185380Ssam    if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Regs.front().first))
1567185380Ssam      Kind = k_DPRRegisterList;
1568185380Ssam    else if (ARMMCRegisterClasses[ARM::SPRRegClassID].
1569185380Ssam             contains(Regs.front().first))
1570185380Ssam      Kind = k_SPRRegisterList;
1571185380Ssam
1572185380Ssam    ARMOperand *Op = new ARMOperand(Kind);
1573185380Ssam    for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator
1574185377Ssam           I = Regs.begin(), E = Regs.end(); I != E; ++I)
1575185380Ssam      Op->Registers.push_back(I->first);
1576185380Ssam    array_pod_sort(Op->Registers.begin(), Op->Registers.end());
1577185380Ssam    Op->StartLoc = StartLoc;
1578185380Ssam    Op->EndLoc = EndLoc;
1579187831Ssam    return Op;
1580185380Ssam  }
1581185380Ssam
1582185380Ssam  static ARMOperand *CreateVectorIndex(unsigned Idx, SMLoc S, SMLoc E,
1583185380Ssam                                       MCContext &Ctx) {
1584185380Ssam    ARMOperand *Op = new ARMOperand(k_VectorIndex);
1585185380Ssam    Op->VectorIndex.Val = Idx;
1586185380Ssam    Op->StartLoc = S;
1587185380Ssam    Op->EndLoc = E;
1588185380Ssam    return Op;
1589185380Ssam  }
1590185380Ssam
1591185380Ssam  static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
1592185380Ssam    ARMOperand *Op = new ARMOperand(k_Immediate);
1593185380Ssam    Op->Imm.Val = Val;
1594185380Ssam    Op->StartLoc = S;
1595185380Ssam    Op->EndLoc = E;
1596185380Ssam    return Op;
1597185380Ssam  }
1598185377Ssam
1599185380Ssam  static ARMOperand *CreateFPImm(unsigned Val, SMLoc S, MCContext &Ctx) {
1600185380Ssam    ARMOperand *Op = new ARMOperand(k_FPImmediate);
1601185380Ssam    Op->FPImm.Val = Val;
1602185380Ssam    Op->StartLoc = S;
1603187831Ssam    Op->EndLoc = S;
1604185380Ssam    return Op;
1605185380Ssam  }
1606185380Ssam
1607185380Ssam  static ARMOperand *CreateMem(unsigned BaseRegNum,
1608185380Ssam                               const MCConstantExpr *OffsetImm,
1609185380Ssam                               unsigned OffsetRegNum,
1610185380Ssam                               ARM_AM::ShiftOpc ShiftType,
1611185380Ssam                               unsigned ShiftImm,
1612185380Ssam                               unsigned Alignment,
1613185380Ssam                               bool isNegative,
1614185380Ssam                               SMLoc S, SMLoc E) {
1615185380Ssam    ARMOperand *Op = new ARMOperand(k_Memory);
1616185380Ssam    Op->Memory.BaseRegNum = BaseRegNum;
1617185380Ssam    Op->Memory.OffsetImm = OffsetImm;
1618185380Ssam    Op->Memory.OffsetRegNum = OffsetRegNum;
1619185380Ssam    Op->Memory.ShiftType = ShiftType;
1620185377Ssam    Op->Memory.ShiftImm = ShiftImm;
1621185380Ssam    Op->Memory.Alignment = Alignment;
1622185380Ssam    Op->Memory.isNegative = isNegative;
1623185380Ssam    Op->StartLoc = S;
1624185380Ssam    Op->EndLoc = E;
1625187831Ssam    return Op;
1626185380Ssam  }
1627185380Ssam
1628185380Ssam  static ARMOperand *CreatePostIdxReg(unsigned RegNum, bool isAdd,
1629185380Ssam                                      ARM_AM::ShiftOpc ShiftTy,
1630185380Ssam                                      unsigned ShiftImm,
1631185380Ssam                                      SMLoc S, SMLoc E) {
1632185380Ssam    ARMOperand *Op = new ARMOperand(k_PostIndexRegister);
1633185380Ssam    Op->PostIdxReg.RegNum = RegNum;
1634185380Ssam    Op->PostIdxReg.isAdd = isAdd;
1635185380Ssam    Op->PostIdxReg.ShiftTy = ShiftTy;
1636185380Ssam    Op->PostIdxReg.ShiftImm = ShiftImm;
1637185380Ssam    Op->StartLoc = S;
1638185380Ssam    Op->EndLoc = E;
1639185380Ssam    return Op;
1640185380Ssam  }
1641185380Ssam
1642185380Ssam  static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) {
1643185380Ssam    ARMOperand *Op = new ARMOperand(k_MemBarrierOpt);
1644185377Ssam    Op->MBOpt.Val = Opt;
1645185380Ssam    Op->StartLoc = S;
1646185380Ssam    Op->EndLoc = S;
1647185380Ssam    return Op;
1648185380Ssam  }
1649187831Ssam
1650185380Ssam  static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) {
1651185380Ssam    ARMOperand *Op = new ARMOperand(k_ProcIFlags);
1652185380Ssam    Op->IFlags.Val = IFlags;
1653185380Ssam    Op->StartLoc = S;
1654185380Ssam    Op->EndLoc = S;
1655185380Ssam    return Op;
1656185380Ssam  }
1657185380Ssam
1658185380Ssam  static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) {
1659185380Ssam    ARMOperand *Op = new ARMOperand(k_MSRMask);
1660185380Ssam    Op->MMask.Val = MMask;
1661185380Ssam    Op->StartLoc = S;
1662185380Ssam    Op->EndLoc = S;
1663185380Ssam    return Op;
1664185380Ssam  }
1665185380Ssam};
1666185380Ssam
1667185380Ssam} // end anonymous namespace.
1668185380Ssam
1669185380Ssamvoid ARMOperand::print(raw_ostream &OS) const {
1670185380Ssam  switch (Kind) {
1671185380Ssam  case k_FPImmediate:
1672185380Ssam    OS << "<fpimm " << getFPImm() << "(" << ARM_AM::getFPImmFloat(getFPImm())
1673185377Ssam       << ") >";
1674185377Ssam    break;
1675185377Ssam  case k_CondCode:
1676185377Ssam    OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">";
1677185377Ssam    break;
1678185377Ssam  case k_CCOut:
1679185377Ssam    OS << "<ccout " << getReg() << ">";
1680185377Ssam    break;
1681187831Ssam  case k_ITCondMask: {
1682187831Ssam    static char MaskStr[][6] = { "()", "(t)", "(e)", "(tt)", "(et)", "(te)",
1683187831Ssam      "(ee)", "(ttt)", "(ett)", "(tet)", "(eet)", "(tte)", "(ete)",
1684187831Ssam      "(tee)", "(eee)" };
1685187831Ssam    assert((ITMask.Mask & 0xf) == ITMask.Mask);
1686187831Ssam    OS << "<it-mask " << MaskStr[ITMask.Mask] << ">";
1687187831Ssam    break;
1688187831Ssam  }
1689187831Ssam  case k_CoprocNum:
1690187831Ssam    OS << "<coprocessor number: " << getCoproc() << ">";
1691187831Ssam    break;
1692187831Ssam  case k_CoprocReg:
1693187831Ssam    OS << "<coprocessor register: " << getCoproc() << ">";
1694187831Ssam    break;
1695187831Ssam  case k_CoprocOption:
1696187831Ssam    OS << "<coprocessor option: " << CoprocOption.Val << ">";
1697187831Ssam    break;
1698187831Ssam  case k_MSRMask:
1699187831Ssam    OS << "<mask: " << getMSRMask() << ">";
1700187831Ssam    break;
1701187831Ssam  case k_Immediate:
1702187831Ssam    getImm()->print(OS);
1703187831Ssam    break;
1704187831Ssam  case k_MemBarrierOpt:
1705185377Ssam    OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">";
1706185377Ssam    break;
1707187831Ssam  case k_Memory:
1708185377Ssam    OS << "<memory "
1709185377Ssam       << " base:" << Memory.BaseRegNum;
1710185377Ssam    OS << ">";
1711185377Ssam    break;
1712185377Ssam  case k_PostIndexRegister:
1713185377Ssam    OS << "post-idx register " << (PostIdxReg.isAdd ? "" : "-")
1714185377Ssam       << PostIdxReg.RegNum;
1715185377Ssam    if (PostIdxReg.ShiftTy != ARM_AM::no_shift)
1716185377Ssam      OS << ARM_AM::getShiftOpcStr(PostIdxReg.ShiftTy) << " "
1717185380Ssam         << PostIdxReg.ShiftImm;
1718185377Ssam    OS << ">";
1719185377Ssam    break;
1720185377Ssam  case k_ProcIFlags: {
1721185377Ssam    OS << "<ARM_PROC::";
1722185377Ssam    unsigned IFlags = getProcIFlags();
1723185377Ssam    for (int i=2; i >= 0; --i)
1724185377Ssam      if (IFlags & (1 << i))
1725185377Ssam        OS << ARM_PROC::IFlagsToString(1 << i);
1726185377Ssam    OS << ">";
1727185377Ssam    break;
1728185377Ssam  }
1729185377Ssam  case k_Register:
1730185377Ssam    OS << "<register " << getReg() << ">";
1731185377Ssam    break;
1732185377Ssam  case k_ShifterImmediate:
1733185377Ssam    OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl")
1734185377Ssam       << " #" << ShifterImm.Imm << ">";
1735185377Ssam    break;
1736185377Ssam  case k_ShiftedRegister:
1737185377Ssam    OS << "<so_reg_reg "
1738185377Ssam       << RegShiftedReg.SrcReg
1739185377Ssam       << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedReg.ShiftImm))
1740185377Ssam       << ", " << RegShiftedReg.ShiftReg << ", "
1741185377Ssam       << ARM_AM::getSORegOffset(RegShiftedReg.ShiftImm)
1742185377Ssam       << ">";
1743185377Ssam    break;
1744185377Ssam  case k_ShiftedImmediate:
1745185377Ssam    OS << "<so_reg_imm "
1746185377Ssam       << RegShiftedImm.SrcReg
1747185377Ssam       << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedImm.ShiftImm))
1748185377Ssam       << ", " << ARM_AM::getSORegOffset(RegShiftedImm.ShiftImm)
1749185377Ssam       << ">";
1750185377Ssam    break;
1751185377Ssam  case k_RotateImmediate:
1752185377Ssam    OS << "<ror " << " #" << (RotImm.Imm * 8) << ">";
1753185377Ssam    break;
1754185377Ssam  case k_BitfieldDescriptor:
1755187831Ssam    OS << "<bitfield " << "lsb: " << Bitfield.LSB
1756187831Ssam       << ", width: " << Bitfield.Width << ">";
1757185377Ssam    break;
1758187831Ssam  case k_RegisterList:
1759187831Ssam  case k_DPRRegisterList:
1760185377Ssam  case k_SPRRegisterList: {
1761187831Ssam    OS << "<register_list ";
1762185377Ssam
1763187831Ssam    const SmallVectorImpl<unsigned> &RegList = getRegList();
1764187831Ssam    for (SmallVectorImpl<unsigned>::const_iterator
1765187831Ssam           I = RegList.begin(), E = RegList.end(); I != E; ) {
1766185377Ssam      OS << *I;
1767187831Ssam      if (++I < E) OS << ", ";
1768185377Ssam    }
1769185377Ssam
1770187831Ssam    OS << ">";
1771187831Ssam    break;
1772185377Ssam  }
1773187831Ssam  case k_Token:
1774185377Ssam    OS << "'" << getToken() << "'";
1775187831Ssam    break;
1776187831Ssam  case k_VectorIndex:
1777187831Ssam    OS << "<vectorindex " << getVectorIndex() << ">";
1778185380Ssam    break;
1779187831Ssam  }
1780185377Ssam}
1781185377Ssam
1782187831Ssam/// @name Auto-generated Match Functions
1783187831Ssam/// {
1784185377Ssam
1785185377Ssamstatic unsigned MatchRegisterName(StringRef Name);
1786185377Ssam
1787187831Ssam/// }
1788187831Ssam
1789187831Ssambool ARMAsmParser::ParseRegister(unsigned &RegNo,
1790187831Ssam                                 SMLoc &StartLoc, SMLoc &EndLoc) {
1791187831Ssam  RegNo = tryParseRegister();
1792185377Ssam
1793187831Ssam  return (RegNo == (unsigned)-1);
1794185377Ssam}
1795185377Ssam
1796185377Ssam/// Try to parse a register name.  The token must be an Identifier when called,
1797185377Ssam/// and if it is a register name the token is eaten and the register number is
1798185377Ssam/// returned.  Otherwise return -1.
1799185377Ssam///
1800185377Ssamint ARMAsmParser::tryParseRegister() {
1801185377Ssam  const AsmToken &Tok = Parser.getTok();
1802187831Ssam  if (Tok.isNot(AsmToken::Identifier)) return -1;
1803185377Ssam
1804185377Ssam  // FIXME: Validate register for the current architecture; we have to do
1805185377Ssam  // validation later, so maybe there is no need for this here.
1806185377Ssam  std::string upperCase = Tok.getString().str();
1807187831Ssam  std::string lowerCase = LowercaseString(upperCase);
1808185377Ssam  unsigned RegNum = MatchRegisterName(lowerCase);
1809185377Ssam  if (!RegNum) {
1810185377Ssam    RegNum = StringSwitch<unsigned>(lowerCase)
1811185377Ssam      .Case("r13", ARM::SP)
1812185377Ssam      .Case("r14", ARM::LR)
1813185377Ssam      .Case("r15", ARM::PC)
1814185377Ssam      .Case("ip", ARM::R12)
1815185377Ssam      .Default(0);
1816187831Ssam  }
1817187831Ssam  if (!RegNum) return -1;
1818185377Ssam
1819185377Ssam  Parser.Lex(); // Eat identifier token.
1820185377Ssam
1821187831Ssam#if 0
1822185377Ssam  // Also check for an index operand. This is only legal for vector registers,
1823187831Ssam  // but that'll get caught OK in operand matching, so we don't need to
1824187831Ssam  // explicitly filter everything else out here.
1825185377Ssam  if (Parser.getTok().is(AsmToken::LBrac)) {
1826187831Ssam    SMLoc SIdx = Parser.getTok().getLoc();
1827187831Ssam    Parser.Lex(); // Eat left bracket token.
1828187831Ssam
1829187831Ssam    const MCExpr *ImmVal;
1830185377Ssam    SMLoc ExprLoc = Parser.getTok().getLoc();
1831185377Ssam    if (getParser().ParseExpression(ImmVal))
1832187831Ssam      return MatchOperand_ParseFail;
1833187831Ssam    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
1834187831Ssam    if (!MCE) {
1835187831Ssam      TokError("immediate value expected for vector index");
1836185377Ssam      return MatchOperand_ParseFail;
1837187831Ssam    }
1838187831Ssam
1839185377Ssam    SMLoc E = Parser.getTok().getLoc();
1840187831Ssam    if (Parser.getTok().isNot(AsmToken::RBrac)) {
1841187831Ssam      Error(E, "']' expected");
1842187831Ssam      return MatchOperand_ParseFail;
1843187831Ssam    }
1844187831Ssam
1845187831Ssam    Parser.Lex(); // Eat right bracket token.
1846187831Ssam
1847187831Ssam    Operands.push_back(ARMOperand::CreateVectorIndex(MCE->getValue(),
1848187831Ssam                                                     SIdx, E,
1849187831Ssam                                                     getContext()));
1850187831Ssam  }
1851187831Ssam#endif
1852187831Ssam
1853185377Ssam  return RegNum;
1854187831Ssam}
1855187831Ssam
1856187831Ssam// Try to parse a shifter  (e.g., "lsl <amt>"). On success, return 0.
1857187831Ssam// If a recoverable error occurs, return 1. If an irrecoverable error
1858187831Ssam// occurs, return -1. An irrecoverable error is one where tokens have been
1859187831Ssam// consumed in the process of trying to parse the shifter (i.e., when it is
1860187831Ssam// indeed a shifter operand, but malformed).
1861187831Ssamint ARMAsmParser::tryParseShiftRegister(
1862187831Ssam                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1863187831Ssam  SMLoc S = Parser.getTok().getLoc();
1864185377Ssam  const AsmToken &Tok = Parser.getTok();
1865187831Ssam  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1866187831Ssam
1867187831Ssam  std::string upperCase = Tok.getString().str();
1868187831Ssam  std::string lowerCase = LowercaseString(upperCase);
1869187831Ssam  ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase)
1870187831Ssam      .Case("lsl", ARM_AM::lsl)
1871187831Ssam      .Case("lsr", ARM_AM::lsr)
1872187831Ssam      .Case("asr", ARM_AM::asr)
1873187831Ssam      .Case("ror", ARM_AM::ror)
1874185377Ssam      .Case("rrx", ARM_AM::rrx)
1875187831Ssam      .Default(ARM_AM::no_shift);
1876187831Ssam
1877185377Ssam  if (ShiftTy == ARM_AM::no_shift)
1878185377Ssam    return 1;
1879187831Ssam
1880187831Ssam  Parser.Lex(); // Eat the operator.
1881187831Ssam
1882185377Ssam  // The source register for the shift has already been added to the
1883187831Ssam  // operand list, so we need to pop it off and combine it into the shifted
1884187831Ssam  // register operand instead.
1885185377Ssam  OwningPtr<ARMOperand> PrevOp((ARMOperand*)Operands.pop_back_val());
1886187831Ssam  if (!PrevOp->isReg())
1887187831Ssam    return Error(PrevOp->getStartLoc(), "shift must be of a register");
1888187831Ssam  int SrcReg = PrevOp->getReg();
1889187831Ssam  int64_t Imm = 0;
1890185377Ssam  int ShiftReg = 0;
1891185377Ssam  if (ShiftTy == ARM_AM::rrx) {
1892185377Ssam    // RRX Doesn't have an explicit shift amount. The encoder expects
1893187831Ssam    // the shift register to be the same as the source register. Seems odd,
1894185377Ssam    // but OK.
1895187831Ssam    ShiftReg = SrcReg;
1896187831Ssam  } else {
1897187831Ssam    // Figure out if this is shifted by a constant or a register (for non-RRX).
1898187831Ssam    if (Parser.getTok().is(AsmToken::Hash)) {
1899187831Ssam      Parser.Lex(); // Eat hash.
1900187831Ssam      SMLoc ImmLoc = Parser.getTok().getLoc();
1901187831Ssam      const MCExpr *ShiftExpr = 0;
1902187831Ssam      if (getParser().ParseExpression(ShiftExpr)) {
1903187831Ssam        Error(ImmLoc, "invalid immediate shift value");
1904187831Ssam        return -1;
1905187831Ssam      }
1906187831Ssam      // The expression must be evaluatable as an immediate.
1907187831Ssam      const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr);
1908187831Ssam      if (!CE) {
1909187831Ssam        Error(ImmLoc, "invalid immediate shift value");
1910187831Ssam        return -1;
1911187831Ssam      }
1912187831Ssam      // Range check the immediate.
1913187831Ssam      // lsl, ror: 0 <= imm <= 31
1914187831Ssam      // lsr, asr: 0 <= imm <= 32
1915187831Ssam      Imm = CE->getValue();
1916187831Ssam      if (Imm < 0 ||
1917185377Ssam          ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) ||
1918187831Ssam          ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) {
1919187831Ssam        Error(ImmLoc, "immediate shift value out of range");
1920187831Ssam        return -1;
1921187831Ssam      }
1922187831Ssam    } else if (Parser.getTok().is(AsmToken::Identifier)) {
1923187831Ssam      ShiftReg = tryParseRegister();
1924185377Ssam      SMLoc L = Parser.getTok().getLoc();
1925185377Ssam      if (ShiftReg == -1) {
1926187831Ssam        Error (L, "expected immediate or register in shift operand");
1927187831Ssam        return -1;
1928187831Ssam      }
1929187831Ssam    } else {
1930187831Ssam      Error (Parser.getTok().getLoc(),
1931185377Ssam                    "expected immediate or register in shift operand");
1932185377Ssam      return -1;
1933185377Ssam    }
1934187831Ssam  }
1935185377Ssam
1936187831Ssam  if (ShiftReg && ShiftTy != ARM_AM::rrx)
1937187831Ssam    Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg,
1938187831Ssam                                                         ShiftReg, Imm,
1939187831Ssam                                               S, Parser.getTok().getLoc()));
1940187831Ssam  else
1941187831Ssam    Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm,
1942187831Ssam                                               S, Parser.getTok().getLoc()));
1943185377Ssam
1944185377Ssam  return 0;
1945185377Ssam}
1946187831Ssam
1947187831Ssam
1948187831Ssam/// Try to parse a register name.  The token must be an Identifier when called.
1949187831Ssam/// If it's a register, an AsmOperand is created. Another AsmOperand is created
1950185377Ssam/// if there is a "writeback". 'true' if it's not a register.
1951185377Ssam///
1952187831Ssam/// TODO this is likely to change to allow different register types and or to
1953185377Ssam/// parse for a specific register type.
1954187831Ssambool ARMAsmParser::
1955185377SsamtryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1956187831Ssam  SMLoc S = Parser.getTok().getLoc();
1957187831Ssam  int RegNo = tryParseRegister();
1958187831Ssam  if (RegNo == -1)
1959185377Ssam    return true;
1960187831Ssam
1961187831Ssam  Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc()));
1962187831Ssam
1963185377Ssam  const AsmToken &ExclaimTok = Parser.getTok();
1964187831Ssam  if (ExclaimTok.is(AsmToken::Exclaim)) {
1965187831Ssam    Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(),
1966187831Ssam                                               ExclaimTok.getLoc()));
1967187831Ssam    Parser.Lex(); // Eat exclaim token
1968187831Ssam    return false;
1969185377Ssam  }
1970187831Ssam
1971187831Ssam  // Also check for an index operand. This is only legal for vector registers,
1972185377Ssam  // but that'll get caught OK in operand matching, so we don't need to
1973185377Ssam  // explicitly filter everything else out here.
1974185377Ssam  if (Parser.getTok().is(AsmToken::LBrac)) {
1975187831Ssam    SMLoc SIdx = Parser.getTok().getLoc();
1976185377Ssam    Parser.Lex(); // Eat left bracket token.
1977185377Ssam
1978185377Ssam    const MCExpr *ImmVal;
1979185377Ssam    SMLoc ExprLoc = Parser.getTok().getLoc();
1980185377Ssam    if (getParser().ParseExpression(ImmVal))
1981187831Ssam      return MatchOperand_ParseFail;
1982187831Ssam    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
1983187831Ssam    if (!MCE) {
1984185377Ssam      TokError("immediate value expected for vector index");
1985185377Ssam      return MatchOperand_ParseFail;
1986185377Ssam    }
1987185377Ssam
1988185377Ssam    SMLoc E = Parser.getTok().getLoc();
1989185377Ssam    if (Parser.getTok().isNot(AsmToken::RBrac)) {
1990185377Ssam      Error(E, "']' expected");
1991185377Ssam      return MatchOperand_ParseFail;
1992185377Ssam    }
1993185377Ssam
1994185377Ssam    Parser.Lex(); // Eat right bracket token.
1995185377Ssam
1996185377Ssam    Operands.push_back(ARMOperand::CreateVectorIndex(MCE->getValue(),
1997185377Ssam                                                     SIdx, E,
1998185377Ssam                                                     getContext()));
1999185377Ssam  }
2000185377Ssam
2001185377Ssam  return false;
2002185377Ssam}
2003185377Ssam
2004185377Ssam/// MatchCoprocessorOperandName - Try to parse an coprocessor related
2005185377Ssam/// instruction with a symbolic operand name. Example: "p1", "p7", "c3",
2006187831Ssam/// "c5", ...
2007187831Ssamstatic int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) {
2008187831Ssam  // Use the same layout as the tablegen'erated register name matcher. Ugly,
2009187831Ssam  // but efficient.
2010187831Ssam  switch (Name.size()) {
2011187831Ssam  default: break;
2012187831Ssam  case 2:
2013187831Ssam    if (Name[0] != CoprocOp)
2014185377Ssam      return -1;
2015185377Ssam    switch (Name[1]) {
2016187831Ssam    default:  return -1;
2017187831Ssam    case '0': return 0;
2018187831Ssam    case '1': return 1;
2019187831Ssam    case '2': return 2;
2020187831Ssam    case '3': return 3;
2021187831Ssam    case '4': return 4;
2022187831Ssam    case '5': return 5;
2023185377Ssam    case '6': return 6;
2024185380Ssam    case '7': return 7;
2025185380Ssam    case '8': return 8;
2026185377Ssam    case '9': return 9;
2027185377Ssam    }
2028185377Ssam    break;
2029187831Ssam  case 3:
2030187831Ssam    if (Name[0] != CoprocOp || Name[1] != '1')
2031187831Ssam      return -1;
2032185380Ssam    switch (Name[2]) {
2033187831Ssam    default:  return -1;
2034185380Ssam    case '0': return 10;
2035187831Ssam    case '1': return 11;
2036185380Ssam    case '2': return 12;
2037187831Ssam    case '3': return 13;
2038185377Ssam    case '4': return 14;
2039185377Ssam    case '5': return 15;
2040185377Ssam    }
2041185377Ssam    break;
2042185380Ssam  }
2043185380Ssam
2044185377Ssam  return -1;
2045185377Ssam}
2046185377Ssam
2047187831Ssam/// parseITCondCode - Try to parse a condition code for an IT instruction.
2048187831SsamARMAsmParser::OperandMatchResultTy ARMAsmParser::
2049187831SsamparseITCondCode(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2050185380Ssam  SMLoc S = Parser.getTok().getLoc();
2051187831Ssam  const AsmToken &Tok = Parser.getTok();
2052185380Ssam  if (!Tok.is(AsmToken::Identifier))
2053187831Ssam    return MatchOperand_NoMatch;
2054187831Ssam  unsigned CC = StringSwitch<unsigned>(Tok.getString())
2055187831Ssam    .Case("eq", ARMCC::EQ)
2056185380Ssam    .Case("ne", ARMCC::NE)
2057187831Ssam    .Case("hs", ARMCC::HS)
2058187831Ssam    .Case("cs", ARMCC::HS)
2059187831Ssam    .Case("lo", ARMCC::LO)
2060187831Ssam    .Case("cc", ARMCC::LO)
2061187831Ssam    .Case("mi", ARMCC::MI)
2062185377Ssam    .Case("pl", ARMCC::PL)
2063185377Ssam    .Case("vs", ARMCC::VS)
2064185377Ssam    .Case("vc", ARMCC::VC)
2065185377Ssam    .Case("hi", ARMCC::HI)
2066185377Ssam    .Case("ls", ARMCC::LS)
2067185377Ssam    .Case("ge", ARMCC::GE)
2068185377Ssam    .Case("lt", ARMCC::LT)
2069185377Ssam    .Case("gt", ARMCC::GT)
2070185377Ssam    .Case("le", ARMCC::LE)
2071185377Ssam    .Case("al", ARMCC::AL)
2072185377Ssam    .Default(~0U);
2073185377Ssam  if (CC == ~0U)
2074185377Ssam    return MatchOperand_NoMatch;
2075185377Ssam  Parser.Lex(); // Eat the token.
2076185377Ssam
2077185377Ssam  Operands.push_back(ARMOperand::CreateCondCode(ARMCC::CondCodes(CC), S));
2078185377Ssam
2079185377Ssam  return MatchOperand_Success;
2080185377Ssam}
2081185377Ssam
2082185377Ssam/// parseCoprocNumOperand - Try to parse an coprocessor number operand. The
2083185377Ssam/// token must be an Identifier when called, and if it is a coprocessor
2084185377Ssam/// number, the token is eaten and the operand is added to the operand list.
2085185377SsamARMAsmParser::OperandMatchResultTy ARMAsmParser::
2086185377SsamparseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2087185377Ssam  SMLoc S = Parser.getTok().getLoc();
2088185377Ssam  const AsmToken &Tok = Parser.getTok();
2089185377Ssam  if (Tok.isNot(AsmToken::Identifier))
2090185377Ssam    return MatchOperand_NoMatch;
2091185377Ssam
2092185377Ssam  int Num = MatchCoprocessorOperandName(Tok.getString(), 'p');
2093185377Ssam  if (Num == -1)
2094185377Ssam    return MatchOperand_NoMatch;
2095185377Ssam
2096185377Ssam  Parser.Lex(); // Eat identifier token.
2097185377Ssam  Operands.push_back(ARMOperand::CreateCoprocNum(Num, S));
2098185377Ssam  return MatchOperand_Success;
2099185377Ssam}
2100185377Ssam
2101185377Ssam/// parseCoprocRegOperand - Try to parse an coprocessor register operand. The
2102185377Ssam/// token must be an Identifier when called, and if it is a coprocessor
2103185377Ssam/// number, the token is eaten and the operand is added to the operand list.
2104185377SsamARMAsmParser::OperandMatchResultTy ARMAsmParser::
2105187831SsamparseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2106185377Ssam  SMLoc S = Parser.getTok().getLoc();
2107185377Ssam  const AsmToken &Tok = Parser.getTok();
2108187831Ssam  if (Tok.isNot(AsmToken::Identifier))
2109187831Ssam    return MatchOperand_NoMatch;
2110187831Ssam
2111185377Ssam  int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c');
2112187831Ssam  if (Reg == -1)
2113185377Ssam    return MatchOperand_NoMatch;
2114185377Ssam
2115185377Ssam  Parser.Lex(); // Eat identifier token.
2116185377Ssam  Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S));
2117185377Ssam  return MatchOperand_Success;
2118185377Ssam}
2119185377Ssam
2120185377Ssam/// parseCoprocOptionOperand - Try to parse an coprocessor option operand.
2121185377Ssam/// coproc_option : '{' imm0_255 '}'
2122185377SsamARMAsmParser::OperandMatchResultTy ARMAsmParser::
2123185377SsamparseCoprocOptionOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2124187831Ssam  SMLoc S = Parser.getTok().getLoc();
2125187831Ssam
2126187831Ssam  // If this isn't a '{', this isn't a coprocessor immediate operand.
2127187831Ssam  if (Parser.getTok().isNot(AsmToken::LCurly))
2128187831Ssam    return MatchOperand_NoMatch;
2129187831Ssam  Parser.Lex(); // Eat the '{'
2130187831Ssam
2131187831Ssam  const MCExpr *Expr;
2132187831Ssam  SMLoc Loc = Parser.getTok().getLoc();
2133187831Ssam  if (getParser().ParseExpression(Expr)) {
2134187831Ssam    Error(Loc, "illegal expression");
2135187831Ssam    return MatchOperand_ParseFail;
2136187831Ssam  }
2137187831Ssam  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
2138187831Ssam  if (!CE || CE->getValue() < 0 || CE->getValue() > 255) {
2139187831Ssam    Error(Loc, "coprocessor option must be an immediate in range [0, 255]");
2140187831Ssam    return MatchOperand_ParseFail;
2141187831Ssam  }
2142187831Ssam  int Val = CE->getValue();
2143187831Ssam
2144187831Ssam  // Check for and consume the closing '}'
2145187831Ssam  if (Parser.getTok().isNot(AsmToken::RCurly))
2146187831Ssam    return MatchOperand_ParseFail;
2147187831Ssam  SMLoc E = Parser.getTok().getLoc();
2148185377Ssam  Parser.Lex(); // Eat the '}'
2149185377Ssam
2150185377Ssam  Operands.push_back(ARMOperand::CreateCoprocOption(Val, S, E));
2151185377Ssam  return MatchOperand_Success;
2152185377Ssam}
2153187831Ssam
2154187831Ssam// For register list parsing, we need to map from raw GPR register numbering
2155187831Ssam// to the enumeration values. The enumeration values aren't sorted by
2156187831Ssam// register number due to our using "sp", "lr" and "pc" as canonical names.
2157187831Ssamstatic unsigned getNextRegister(unsigned Reg) {
2158187831Ssam  // If this is a GPR, we need to do it manually, otherwise we can rely
2159187831Ssam  // on the sort ordering of the enumeration since the other reg-classes
2160185377Ssam  // are sane.
2161185377Ssam  if (!ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg))
2162185377Ssam    return Reg + 1;
2163185377Ssam  switch(Reg) {
2164185377Ssam  default: assert(0 && "Invalid GPR number!");
2165187831Ssam  case ARM::R0:  return ARM::R1;  case ARM::R1:  return ARM::R2;
2166185377Ssam  case ARM::R2:  return ARM::R3;  case ARM::R3:  return ARM::R4;
2167187831Ssam  case ARM::R4:  return ARM::R5;  case ARM::R5:  return ARM::R6;
2168187831Ssam  case ARM::R6:  return ARM::R7;  case ARM::R7:  return ARM::R8;
2169187831Ssam  case ARM::R8:  return ARM::R9;  case ARM::R9:  return ARM::R10;
2170187831Ssam  case ARM::R10: return ARM::R11; case ARM::R11: return ARM::R12;
2171187831Ssam  case ARM::R12: return ARM::SP;  case ARM::SP:  return ARM::LR;
2172185377Ssam  case ARM::LR:  return ARM::PC;  case ARM::PC:  return ARM::R0;
2173187831Ssam  }
2174187831Ssam}
2175187831Ssam
2176185377Ssam/// Parse a register list.
2177187831Ssambool ARMAsmParser::
2178187831SsamparseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2179187831Ssam  assert(Parser.getTok().is(AsmToken::LCurly) &&
2180187831Ssam         "Token is not a Left Curly Brace");
2181187831Ssam  SMLoc S = Parser.getTok().getLoc();
2182187831Ssam  Parser.Lex(); // Eat '{' token.
2183187831Ssam  SMLoc RegLoc = Parser.getTok().getLoc();
2184187831Ssam
2185187831Ssam  // Check the first register in the list to see what register class
2186187831Ssam  // this is a list of.
2187187831Ssam  int Reg = tryParseRegister();
2188187831Ssam  if (Reg == -1)
2189187831Ssam    return Error(RegLoc, "register expected");
2190187831Ssam
2191187831Ssam  MCRegisterClass *RC;
2192187831Ssam  if (ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg))
2193187831Ssam    RC = &ARMMCRegisterClasses[ARM::GPRRegClassID];
2194187831Ssam  else if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg))
2195187831Ssam    RC = &ARMMCRegisterClasses[ARM::DPRRegClassID];
2196185377Ssam  else if (ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg))
2197187831Ssam    RC = &ARMMCRegisterClasses[ARM::SPRRegClassID];
2198187831Ssam  else
2199187831Ssam    return Error(RegLoc, "invalid register in register list");
2200187831Ssam
2201187831Ssam  // The reglist instructions have at most 16 registers, so reserve
2202187831Ssam  // space for that many.
2203187831Ssam  SmallVector<std::pair<unsigned, SMLoc>, 16> Registers;
2204187831Ssam  // Store the first register.
2205187831Ssam  Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc));
2206187831Ssam
2207187831Ssam  // This starts immediately after the first register token in the list,
2208187831Ssam  // so we can see either a comma or a minus (range separator) as a legal
2209187831Ssam  // next token.
2210187831Ssam  while (Parser.getTok().is(AsmToken::Comma) ||
2211187831Ssam         Parser.getTok().is(AsmToken::Minus)) {
2212187831Ssam    if (Parser.getTok().is(AsmToken::Minus)) {
2213187831Ssam      Parser.Lex(); // Eat the comma.
2214187831Ssam      SMLoc EndLoc = Parser.getTok().getLoc();
2215187831Ssam      int EndReg = tryParseRegister();
2216187831Ssam      if (EndReg == -1)
2217185377Ssam        return Error(EndLoc, "register expected");
2218187831Ssam      // If the register is the same as the start reg, there's nothing
2219187831Ssam      // more to do.
2220187831Ssam      if (Reg == EndReg)
2221187831Ssam        continue;
2222188084Ssam      // The register must be in the same register class as the first.
2223187831Ssam      if (!RC->contains(EndReg))
2224187831Ssam        return Error(EndLoc, "invalid register in register list");
2225187831Ssam      // Ranges must go from low to high.
2226187831Ssam      if (getARMRegisterNumbering(Reg) > getARMRegisterNumbering(EndReg))
2227187831Ssam        return Error(EndLoc, "bad range in register list");
2228187831Ssam
2229187831Ssam      // Add all the registers in the range to the register list.
2230187831Ssam      while (Reg != EndReg) {
2231187831Ssam        Reg = getNextRegister(Reg);
2232187831Ssam        Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc));
2233187831Ssam      }
2234187831Ssam      continue;
2235187831Ssam    }
2236187831Ssam    Parser.Lex(); // Eat the comma.
2237187831Ssam    RegLoc = Parser.getTok().getLoc();
2238187831Ssam    int OldReg = Reg;
2239187831Ssam    Reg = tryParseRegister();
2240187831Ssam    if (Reg == -1)
2241187831Ssam      return Error(RegLoc, "register expected");
2242187831Ssam    // The register must be in the same register class as the first.
2243187831Ssam    if (!RC->contains(Reg))
2244187831Ssam      return Error(RegLoc, "invalid register in register list");
2245187831Ssam    // List must be monotonically increasing.
2246187831Ssam    if (getARMRegisterNumbering(Reg) <= getARMRegisterNumbering(OldReg))
2247187831Ssam      return Error(RegLoc, "register list not in ascending order");
2248187831Ssam    // VFP register lists must also be contiguous.
2249185377Ssam    // It's OK to use the enumeration values directly here rather, as the
2250185377Ssam    // VFP register classes have the enum sorted properly.
2251187831Ssam    if (RC != &ARMMCRegisterClasses[ARM::GPRRegClassID] &&
2252187831Ssam        Reg != OldReg + 1)
2253187831Ssam      return Error(RegLoc, "non-contiguous register range");
2254187831Ssam    Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc));
2255185377Ssam  }
2256185377Ssam
2257185377Ssam  SMLoc E = Parser.getTok().getLoc();
2258187831Ssam  if (Parser.getTok().isNot(AsmToken::RCurly))
2259185377Ssam    return Error(E, "'}' expected");
2260187831Ssam  Parser.Lex(); // Eat '}' token.
2261187831Ssam
2262187831Ssam  Operands.push_back(ARMOperand::CreateRegList(Registers, S, E));
2263187831Ssam  return false;
2264187831Ssam}
2265185377Ssam
2266187831Ssam/// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options.
2267187831SsamARMAsmParser::OperandMatchResultTy ARMAsmParser::
2268187831SsamparseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2269185377Ssam  SMLoc S = Parser.getTok().getLoc();
2270187831Ssam  const AsmToken &Tok = Parser.getTok();
2271187831Ssam  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
2272187831Ssam  StringRef OptStr = Tok.getString();
2273187831Ssam
2274187831Ssam  unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size()))
2275187831Ssam    .Case("sy",    ARM_MB::SY)
2276187831Ssam    .Case("st",    ARM_MB::ST)
2277187831Ssam    .Case("sh",    ARM_MB::ISH)
2278187831Ssam    .Case("ish",   ARM_MB::ISH)
2279187831Ssam    .Case("shst",  ARM_MB::ISHST)
2280187831Ssam    .Case("ishst", ARM_MB::ISHST)
2281187831Ssam    .Case("nsh",   ARM_MB::NSH)
2282187831Ssam    .Case("un",    ARM_MB::NSH)
2283185377Ssam    .Case("nshst", ARM_MB::NSHST)
2284185377Ssam    .Case("unst",  ARM_MB::NSHST)
2285187831Ssam    .Case("osh",   ARM_MB::OSH)
2286187831Ssam    .Case("oshst", ARM_MB::OSHST)
2287187831Ssam    .Default(~0U);
2288187831Ssam
2289187831Ssam  if (Opt == ~0U)
2290187831Ssam    return MatchOperand_NoMatch;
2291187831Ssam
2292187831Ssam  Parser.Lex(); // Eat identifier token.
2293187831Ssam  Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S));
2294187831Ssam  return MatchOperand_Success;
2295187831Ssam}
2296185377Ssam
2297187831Ssam/// parseProcIFlagsOperand - Try to parse iflags from CPS instruction.
2298187831SsamARMAsmParser::OperandMatchResultTy ARMAsmParser::
2299187831SsamparseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2300187831Ssam  SMLoc S = Parser.getTok().getLoc();
2301187831Ssam  const AsmToken &Tok = Parser.getTok();
2302187831Ssam  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
2303187831Ssam  StringRef IFlagsStr = Tok.getString();
2304187831Ssam
2305187831Ssam  // An iflags string of "none" is interpreted to mean that none of the AIF
2306187831Ssam  // bits are set.  Not a terribly useful instruction, but a valid encoding.
2307187831Ssam  unsigned IFlags = 0;
2308187831Ssam  if (IFlagsStr != "none") {
2309187831Ssam        for (int i = 0, e = IFlagsStr.size(); i != e; ++i) {
2310187831Ssam      unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1))
2311187831Ssam        .Case("a", ARM_PROC::A)
2312187831Ssam        .Case("i", ARM_PROC::I)
2313187831Ssam        .Case("f", ARM_PROC::F)
2314187831Ssam        .Default(~0U);
2315187831Ssam
2316187831Ssam      // If some specific iflag is already set, it means that some letter is
2317187831Ssam      // present more than once, this is not acceptable.
2318187831Ssam      if (Flag == ~0U || (IFlags & Flag))
2319187831Ssam        return MatchOperand_NoMatch;
2320185377Ssam
2321187831Ssam      IFlags |= Flag;
2322187831Ssam    }
2323187831Ssam  }
2324187831Ssam
2325187831Ssam  Parser.Lex(); // Eat identifier token.
2326187831Ssam  Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S));
2327187831Ssam  return MatchOperand_Success;
2328185377Ssam}
2329187831Ssam
2330185377Ssam/// parseMSRMaskOperand - Try to parse mask flags from MSR instruction.
2331187831SsamARMAsmParser::OperandMatchResultTy ARMAsmParser::
2332187831SsamparseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2333185377Ssam  SMLoc S = Parser.getTok().getLoc();
2334187831Ssam  const AsmToken &Tok = Parser.getTok();
2335187831Ssam  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
2336185377Ssam  StringRef Mask = Tok.getString();
2337187831Ssam
2338185377Ssam  if (isMClass()) {
2339187831Ssam    // See ARMv6-M 10.1.1
2340187831Ssam    unsigned FlagsVal = StringSwitch<unsigned>(Mask)
2341187831Ssam      .Case("apsr", 0)
2342187831Ssam      .Case("iapsr", 1)
2343187831Ssam      .Case("eapsr", 2)
2344187831Ssam      .Case("xpsr", 3)
2345187831Ssam      .Case("ipsr", 5)
2346187831Ssam      .Case("epsr", 6)
2347185377Ssam      .Case("iepsr", 7)
2348187831Ssam      .Case("msp", 8)
2349187831Ssam      .Case("psp", 9)
2350187831Ssam      .Case("primask", 16)
2351187831Ssam      .Case("basepri", 17)
2352187831Ssam      .Case("basepri_max", 18)
2353185377Ssam      .Case("faultmask", 19)
2354187831Ssam      .Case("control", 20)
2355185377Ssam      .Default(~0U);
2356187831Ssam
2357185377Ssam    if (FlagsVal == ~0U)
2358187831Ssam      return MatchOperand_NoMatch;
2359187831Ssam
2360187831Ssam    if (!hasV7Ops() && FlagsVal >= 17 && FlagsVal <= 19)
2361187831Ssam      // basepri, basepri_max and faultmask only valid for V7m.
2362185377Ssam      return MatchOperand_NoMatch;
2363187831Ssam
2364187831Ssam    Parser.Lex(); // Eat identifier token.
2365185377Ssam    Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
2366187831Ssam    return MatchOperand_Success;
2367187831Ssam  }
2368185377Ssam
2369187831Ssam  // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf"
2370185377Ssam  size_t Start = 0, Next = Mask.find('_');
2371187831Ssam  StringRef Flags = "";
2372187831Ssam  std::string SpecReg = LowercaseString(Mask.slice(Start, Next));
2373187831Ssam  if (Next != StringRef::npos)
2374187831Ssam    Flags = Mask.slice(Next+1, Mask.size());
2375187831Ssam
2376187831Ssam  // FlagsVal contains the complete mask:
2377187831Ssam  // 3-0: Mask
2378187831Ssam  // 4: Special Reg (cpsr, apsr => 0; spsr => 1)
2379187831Ssam  unsigned FlagsVal = 0;
2380187831Ssam
2381187831Ssam  if (SpecReg == "apsr") {
2382187831Ssam    FlagsVal = StringSwitch<unsigned>(Flags)
2383187831Ssam    .Case("nzcvq",  0x8) // same as CPSR_f
2384187831Ssam    .Case("g",      0x4) // same as CPSR_s
2385187831Ssam    .Case("nzcvqg", 0xc) // same as CPSR_fs
2386187831Ssam    .Default(~0U);
2387187831Ssam
2388187831Ssam    if (FlagsVal == ~0U) {
2389185377Ssam      if (!Flags.empty())
2390185377Ssam        return MatchOperand_NoMatch;
2391185377Ssam      else
2392187831Ssam        FlagsVal = 8; // No flag
2393187831Ssam    }
2394187831Ssam  } else if (SpecReg == "cpsr" || SpecReg == "spsr") {
2395187831Ssam    if (Flags == "all") // cpsr_all is an alias for cpsr_fc
2396187831Ssam      Flags = "fc";
2397187831Ssam    for (int i = 0, e = Flags.size(); i != e; ++i) {
2398187831Ssam      unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1))
2399185377Ssam      .Case("c", 1)
2400187831Ssam      .Case("x", 2)
2401187831Ssam      .Case("s", 4)
2402187831Ssam      .Case("f", 8)
2403185377Ssam      .Default(~0U);
2404187831Ssam
2405187831Ssam      // If some specific flag is already set, it means that some letter is
2406185377Ssam      // present more than once, this is not acceptable.
2407      if (FlagsVal == ~0U || (FlagsVal & Flag))
2408        return MatchOperand_NoMatch;
2409      FlagsVal |= Flag;
2410    }
2411  } else // No match for special register.
2412    return MatchOperand_NoMatch;
2413
2414  // Special register without flags are equivalent to "fc" flags.
2415  if (!FlagsVal)
2416    FlagsVal = 0x9;
2417
2418  // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1)
2419  if (SpecReg == "spsr")
2420    FlagsVal |= 16;
2421
2422  Parser.Lex(); // Eat identifier token.
2423  Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
2424  return MatchOperand_Success;
2425}
2426
2427ARMAsmParser::OperandMatchResultTy ARMAsmParser::
2428parsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands, StringRef Op,
2429            int Low, int High) {
2430  const AsmToken &Tok = Parser.getTok();
2431  if (Tok.isNot(AsmToken::Identifier)) {
2432    Error(Parser.getTok().getLoc(), Op + " operand expected.");
2433    return MatchOperand_ParseFail;
2434  }
2435  StringRef ShiftName = Tok.getString();
2436  std::string LowerOp = LowercaseString(Op);
2437  std::string UpperOp = UppercaseString(Op);
2438  if (ShiftName != LowerOp && ShiftName != UpperOp) {
2439    Error(Parser.getTok().getLoc(), Op + " operand expected.");
2440    return MatchOperand_ParseFail;
2441  }
2442  Parser.Lex(); // Eat shift type token.
2443
2444  // There must be a '#' and a shift amount.
2445  if (Parser.getTok().isNot(AsmToken::Hash)) {
2446    Error(Parser.getTok().getLoc(), "'#' expected");
2447    return MatchOperand_ParseFail;
2448  }
2449  Parser.Lex(); // Eat hash token.
2450
2451  const MCExpr *ShiftAmount;
2452  SMLoc Loc = Parser.getTok().getLoc();
2453  if (getParser().ParseExpression(ShiftAmount)) {
2454    Error(Loc, "illegal expression");
2455    return MatchOperand_ParseFail;
2456  }
2457  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
2458  if (!CE) {
2459    Error(Loc, "constant expression expected");
2460    return MatchOperand_ParseFail;
2461  }
2462  int Val = CE->getValue();
2463  if (Val < Low || Val > High) {
2464    Error(Loc, "immediate value out of range");
2465    return MatchOperand_ParseFail;
2466  }
2467
2468  Operands.push_back(ARMOperand::CreateImm(CE, Loc, Parser.getTok().getLoc()));
2469
2470  return MatchOperand_Success;
2471}
2472
2473ARMAsmParser::OperandMatchResultTy ARMAsmParser::
2474parseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2475  const AsmToken &Tok = Parser.getTok();
2476  SMLoc S = Tok.getLoc();
2477  if (Tok.isNot(AsmToken::Identifier)) {
2478    Error(Tok.getLoc(), "'be' or 'le' operand expected");
2479    return MatchOperand_ParseFail;
2480  }
2481  int Val = StringSwitch<int>(Tok.getString())
2482    .Case("be", 1)
2483    .Case("le", 0)
2484    .Default(-1);
2485  Parser.Lex(); // Eat the token.
2486
2487  if (Val == -1) {
2488    Error(Tok.getLoc(), "'be' or 'le' operand expected");
2489    return MatchOperand_ParseFail;
2490  }
2491  Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::Create(Val,
2492                                                                  getContext()),
2493                                           S, Parser.getTok().getLoc()));
2494  return MatchOperand_Success;
2495}
2496
2497/// parseShifterImm - Parse the shifter immediate operand for SSAT/USAT
2498/// instructions. Legal values are:
2499///     lsl #n  'n' in [0,31]
2500///     asr #n  'n' in [1,32]
2501///             n == 32 encoded as n == 0.
2502ARMAsmParser::OperandMatchResultTy ARMAsmParser::
2503parseShifterImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2504  const AsmToken &Tok = Parser.getTok();
2505  SMLoc S = Tok.getLoc();
2506  if (Tok.isNot(AsmToken::Identifier)) {
2507    Error(S, "shift operator 'asr' or 'lsl' expected");
2508    return MatchOperand_ParseFail;
2509  }
2510  StringRef ShiftName = Tok.getString();
2511  bool isASR;
2512  if (ShiftName == "lsl" || ShiftName == "LSL")
2513    isASR = false;
2514  else if (ShiftName == "asr" || ShiftName == "ASR")
2515    isASR = true;
2516  else {
2517    Error(S, "shift operator 'asr' or 'lsl' expected");
2518    return MatchOperand_ParseFail;
2519  }
2520  Parser.Lex(); // Eat the operator.
2521
2522  // A '#' and a shift amount.
2523  if (Parser.getTok().isNot(AsmToken::Hash)) {
2524    Error(Parser.getTok().getLoc(), "'#' expected");
2525    return MatchOperand_ParseFail;
2526  }
2527  Parser.Lex(); // Eat hash token.
2528
2529  const MCExpr *ShiftAmount;
2530  SMLoc E = Parser.getTok().getLoc();
2531  if (getParser().ParseExpression(ShiftAmount)) {
2532    Error(E, "malformed shift expression");
2533    return MatchOperand_ParseFail;
2534  }
2535  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
2536  if (!CE) {
2537    Error(E, "shift amount must be an immediate");
2538    return MatchOperand_ParseFail;
2539  }
2540
2541  int64_t Val = CE->getValue();
2542  if (isASR) {
2543    // Shift amount must be in [1,32]
2544    if (Val < 1 || Val > 32) {
2545      Error(E, "'asr' shift amount must be in range [1,32]");
2546      return MatchOperand_ParseFail;
2547    }
2548    // asr #32 encoded as asr #0, but is not allowed in Thumb2 mode.
2549    if (isThumb() && Val == 32) {
2550      Error(E, "'asr #32' shift amount not allowed in Thumb mode");
2551      return MatchOperand_ParseFail;
2552    }
2553    if (Val == 32) Val = 0;
2554  } else {
2555    // Shift amount must be in [1,32]
2556    if (Val < 0 || Val > 31) {
2557      Error(E, "'lsr' shift amount must be in range [0,31]");
2558      return MatchOperand_ParseFail;
2559    }
2560  }
2561
2562  E = Parser.getTok().getLoc();
2563  Operands.push_back(ARMOperand::CreateShifterImm(isASR, Val, S, E));
2564
2565  return MatchOperand_Success;
2566}
2567
2568/// parseRotImm - Parse the shifter immediate operand for SXTB/UXTB family
2569/// of instructions. Legal values are:
2570///     ror #n  'n' in {0, 8, 16, 24}
2571ARMAsmParser::OperandMatchResultTy ARMAsmParser::
2572parseRotImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2573  const AsmToken &Tok = Parser.getTok();
2574  SMLoc S = Tok.getLoc();
2575  if (Tok.isNot(AsmToken::Identifier))
2576    return MatchOperand_NoMatch;
2577  StringRef ShiftName = Tok.getString();
2578  if (ShiftName != "ror" && ShiftName != "ROR")
2579    return MatchOperand_NoMatch;
2580  Parser.Lex(); // Eat the operator.
2581
2582  // A '#' and a rotate amount.
2583  if (Parser.getTok().isNot(AsmToken::Hash)) {
2584    Error(Parser.getTok().getLoc(), "'#' expected");
2585    return MatchOperand_ParseFail;
2586  }
2587  Parser.Lex(); // Eat hash token.
2588
2589  const MCExpr *ShiftAmount;
2590  SMLoc E = Parser.getTok().getLoc();
2591  if (getParser().ParseExpression(ShiftAmount)) {
2592    Error(E, "malformed rotate expression");
2593    return MatchOperand_ParseFail;
2594  }
2595  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
2596  if (!CE) {
2597    Error(E, "rotate amount must be an immediate");
2598    return MatchOperand_ParseFail;
2599  }
2600
2601  int64_t Val = CE->getValue();
2602  // Shift amount must be in {0, 8, 16, 24} (0 is undocumented extension)
2603  // normally, zero is represented in asm by omitting the rotate operand
2604  // entirely.
2605  if (Val != 8 && Val != 16 && Val != 24 && Val != 0) {
2606    Error(E, "'ror' rotate amount must be 8, 16, or 24");
2607    return MatchOperand_ParseFail;
2608  }
2609
2610  E = Parser.getTok().getLoc();
2611  Operands.push_back(ARMOperand::CreateRotImm(Val, S, E));
2612
2613  return MatchOperand_Success;
2614}
2615
2616ARMAsmParser::OperandMatchResultTy ARMAsmParser::
2617parseBitfield(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2618  SMLoc S = Parser.getTok().getLoc();
2619  // The bitfield descriptor is really two operands, the LSB and the width.
2620  if (Parser.getTok().isNot(AsmToken::Hash)) {
2621    Error(Parser.getTok().getLoc(), "'#' expected");
2622    return MatchOperand_ParseFail;
2623  }
2624  Parser.Lex(); // Eat hash token.
2625
2626  const MCExpr *LSBExpr;
2627  SMLoc E = Parser.getTok().getLoc();
2628  if (getParser().ParseExpression(LSBExpr)) {
2629    Error(E, "malformed immediate expression");
2630    return MatchOperand_ParseFail;
2631  }
2632  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LSBExpr);
2633  if (!CE) {
2634    Error(E, "'lsb' operand must be an immediate");
2635    return MatchOperand_ParseFail;
2636  }
2637
2638  int64_t LSB = CE->getValue();
2639  // The LSB must be in the range [0,31]
2640  if (LSB < 0 || LSB > 31) {
2641    Error(E, "'lsb' operand must be in the range [0,31]");
2642    return MatchOperand_ParseFail;
2643  }
2644  E = Parser.getTok().getLoc();
2645
2646  // Expect another immediate operand.
2647  if (Parser.getTok().isNot(AsmToken::Comma)) {
2648    Error(Parser.getTok().getLoc(), "too few operands");
2649    return MatchOperand_ParseFail;
2650  }
2651  Parser.Lex(); // Eat hash token.
2652  if (Parser.getTok().isNot(AsmToken::Hash)) {
2653    Error(Parser.getTok().getLoc(), "'#' expected");
2654    return MatchOperand_ParseFail;
2655  }
2656  Parser.Lex(); // Eat hash token.
2657
2658  const MCExpr *WidthExpr;
2659  if (getParser().ParseExpression(WidthExpr)) {
2660    Error(E, "malformed immediate expression");
2661    return MatchOperand_ParseFail;
2662  }
2663  CE = dyn_cast<MCConstantExpr>(WidthExpr);
2664  if (!CE) {
2665    Error(E, "'width' operand must be an immediate");
2666    return MatchOperand_ParseFail;
2667  }
2668
2669  int64_t Width = CE->getValue();
2670  // The LSB must be in the range [1,32-lsb]
2671  if (Width < 1 || Width > 32 - LSB) {
2672    Error(E, "'width' operand must be in the range [1,32-lsb]");
2673    return MatchOperand_ParseFail;
2674  }
2675  E = Parser.getTok().getLoc();
2676
2677  Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, E));
2678
2679  return MatchOperand_Success;
2680}
2681
2682ARMAsmParser::OperandMatchResultTy ARMAsmParser::
2683parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2684  // Check for a post-index addressing register operand. Specifically:
2685  // postidx_reg := '+' register {, shift}
2686  //              | '-' register {, shift}
2687  //              | register {, shift}
2688
2689  // This method must return MatchOperand_NoMatch without consuming any tokens
2690  // in the case where there is no match, as other alternatives take other
2691  // parse methods.
2692  AsmToken Tok = Parser.getTok();
2693  SMLoc S = Tok.getLoc();
2694  bool haveEaten = false;
2695  bool isAdd = true;
2696  int Reg = -1;
2697  if (Tok.is(AsmToken::Plus)) {
2698    Parser.Lex(); // Eat the '+' token.
2699    haveEaten = true;
2700  } else if (Tok.is(AsmToken::Minus)) {
2701    Parser.Lex(); // Eat the '-' token.
2702    isAdd = false;
2703    haveEaten = true;
2704  }
2705  if (Parser.getTok().is(AsmToken::Identifier))
2706    Reg = tryParseRegister();
2707  if (Reg == -1) {
2708    if (!haveEaten)
2709      return MatchOperand_NoMatch;
2710    Error(Parser.getTok().getLoc(), "register expected");
2711    return MatchOperand_ParseFail;
2712  }
2713  SMLoc E = Parser.getTok().getLoc();
2714
2715  ARM_AM::ShiftOpc ShiftTy = ARM_AM::no_shift;
2716  unsigned ShiftImm = 0;
2717  if (Parser.getTok().is(AsmToken::Comma)) {
2718    Parser.Lex(); // Eat the ','.
2719    if (parseMemRegOffsetShift(ShiftTy, ShiftImm))
2720      return MatchOperand_ParseFail;
2721  }
2722
2723  Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy,
2724                                                  ShiftImm, S, E));
2725
2726  return MatchOperand_Success;
2727}
2728
2729ARMAsmParser::OperandMatchResultTy ARMAsmParser::
2730parseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2731  // Check for a post-index addressing register operand. Specifically:
2732  // am3offset := '+' register
2733  //              | '-' register
2734  //              | register
2735  //              | # imm
2736  //              | # + imm
2737  //              | # - imm
2738
2739  // This method must return MatchOperand_NoMatch without consuming any tokens
2740  // in the case where there is no match, as other alternatives take other
2741  // parse methods.
2742  AsmToken Tok = Parser.getTok();
2743  SMLoc S = Tok.getLoc();
2744
2745  // Do immediates first, as we always parse those if we have a '#'.
2746  if (Parser.getTok().is(AsmToken::Hash)) {
2747    Parser.Lex(); // Eat the '#'.
2748    // Explicitly look for a '-', as we need to encode negative zero
2749    // differently.
2750    bool isNegative = Parser.getTok().is(AsmToken::Minus);
2751    const MCExpr *Offset;
2752    if (getParser().ParseExpression(Offset))
2753      return MatchOperand_ParseFail;
2754    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset);
2755    if (!CE) {
2756      Error(S, "constant expression expected");
2757      return MatchOperand_ParseFail;
2758    }
2759    SMLoc E = Tok.getLoc();
2760    // Negative zero is encoded as the flag value INT32_MIN.
2761    int32_t Val = CE->getValue();
2762    if (isNegative && Val == 0)
2763      Val = INT32_MIN;
2764
2765    Operands.push_back(
2766      ARMOperand::CreateImm(MCConstantExpr::Create(Val, getContext()), S, E));
2767
2768    return MatchOperand_Success;
2769  }
2770
2771
2772  bool haveEaten = false;
2773  bool isAdd = true;
2774  int Reg = -1;
2775  if (Tok.is(AsmToken::Plus)) {
2776    Parser.Lex(); // Eat the '+' token.
2777    haveEaten = true;
2778  } else if (Tok.is(AsmToken::Minus)) {
2779    Parser.Lex(); // Eat the '-' token.
2780    isAdd = false;
2781    haveEaten = true;
2782  }
2783  if (Parser.getTok().is(AsmToken::Identifier))
2784    Reg = tryParseRegister();
2785  if (Reg == -1) {
2786    if (!haveEaten)
2787      return MatchOperand_NoMatch;
2788    Error(Parser.getTok().getLoc(), "register expected");
2789    return MatchOperand_ParseFail;
2790  }
2791  SMLoc E = Parser.getTok().getLoc();
2792
2793  Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ARM_AM::no_shift,
2794                                                  0, S, E));
2795
2796  return MatchOperand_Success;
2797}
2798
2799/// cvtT2LdrdPre - Convert parsed operands to MCInst.
2800/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2801/// when they refer multiple MIOperands inside a single one.
2802bool ARMAsmParser::
2803cvtT2LdrdPre(MCInst &Inst, unsigned Opcode,
2804             const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2805  // Rt, Rt2
2806  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
2807  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
2808  // Create a writeback register dummy placeholder.
2809  Inst.addOperand(MCOperand::CreateReg(0));
2810  // addr
2811  ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2);
2812  // pred
2813  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2814  return true;
2815}
2816
2817/// cvtT2StrdPre - Convert parsed operands to MCInst.
2818/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2819/// when they refer multiple MIOperands inside a single one.
2820bool ARMAsmParser::
2821cvtT2StrdPre(MCInst &Inst, unsigned Opcode,
2822             const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2823  // Create a writeback register dummy placeholder.
2824  Inst.addOperand(MCOperand::CreateReg(0));
2825  // Rt, Rt2
2826  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
2827  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
2828  // addr
2829  ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2);
2830  // pred
2831  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2832  return true;
2833}
2834
2835/// cvtLdWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst.
2836/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2837/// when they refer multiple MIOperands inside a single one.
2838bool ARMAsmParser::
2839cvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
2840                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2841  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
2842
2843  // Create a writeback register dummy placeholder.
2844  Inst.addOperand(MCOperand::CreateImm(0));
2845
2846  ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2);
2847  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2848  return true;
2849}
2850
2851/// cvtStWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst.
2852/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2853/// when they refer multiple MIOperands inside a single one.
2854bool ARMAsmParser::
2855cvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
2856                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2857  // Create a writeback register dummy placeholder.
2858  Inst.addOperand(MCOperand::CreateImm(0));
2859  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
2860  ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2);
2861  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2862  return true;
2863}
2864
2865/// cvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
2866/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2867/// when they refer multiple MIOperands inside a single one.
2868bool ARMAsmParser::
2869cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
2870                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2871  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
2872
2873  // Create a writeback register dummy placeholder.
2874  Inst.addOperand(MCOperand::CreateImm(0));
2875
2876  ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3);
2877  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2878  return true;
2879}
2880
2881/// cvtLdWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst.
2882/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2883/// when they refer multiple MIOperands inside a single one.
2884bool ARMAsmParser::
2885cvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
2886                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2887  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
2888
2889  // Create a writeback register dummy placeholder.
2890  Inst.addOperand(MCOperand::CreateImm(0));
2891
2892  ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2);
2893  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2894  return true;
2895}
2896
2897
2898/// cvtStWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst.
2899/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2900/// when they refer multiple MIOperands inside a single one.
2901bool ARMAsmParser::
2902cvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
2903                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2904  // Create a writeback register dummy placeholder.
2905  Inst.addOperand(MCOperand::CreateImm(0));
2906  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
2907  ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2);
2908  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2909  return true;
2910}
2911
2912/// cvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
2913/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2914/// when they refer multiple MIOperands inside a single one.
2915bool ARMAsmParser::
2916cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
2917                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2918  // Create a writeback register dummy placeholder.
2919  Inst.addOperand(MCOperand::CreateImm(0));
2920  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
2921  ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3);
2922  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2923  return true;
2924}
2925
2926/// cvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
2927/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2928/// when they refer multiple MIOperands inside a single one.
2929bool ARMAsmParser::
2930cvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
2931                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2932  // Create a writeback register dummy placeholder.
2933  Inst.addOperand(MCOperand::CreateImm(0));
2934  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
2935  ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3);
2936  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2937  return true;
2938}
2939
2940/// cvtLdExtTWriteBackImm - Convert parsed operands to MCInst.
2941/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2942/// when they refer multiple MIOperands inside a single one.
2943bool ARMAsmParser::
2944cvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
2945                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2946  // Rt
2947  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
2948  // Create a writeback register dummy placeholder.
2949  Inst.addOperand(MCOperand::CreateImm(0));
2950  // addr
2951  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
2952  // offset
2953  ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1);
2954  // pred
2955  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2956  return true;
2957}
2958
2959/// cvtLdExtTWriteBackReg - Convert parsed operands to MCInst.
2960/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2961/// when they refer multiple MIOperands inside a single one.
2962bool ARMAsmParser::
2963cvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
2964                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2965  // Rt
2966  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
2967  // Create a writeback register dummy placeholder.
2968  Inst.addOperand(MCOperand::CreateImm(0));
2969  // addr
2970  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
2971  // offset
2972  ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2);
2973  // pred
2974  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2975  return true;
2976}
2977
2978/// cvtStExtTWriteBackImm - Convert parsed operands to MCInst.
2979/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2980/// when they refer multiple MIOperands inside a single one.
2981bool ARMAsmParser::
2982cvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
2983                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2984  // Create a writeback register dummy placeholder.
2985  Inst.addOperand(MCOperand::CreateImm(0));
2986  // Rt
2987  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
2988  // addr
2989  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
2990  // offset
2991  ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1);
2992  // pred
2993  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2994  return true;
2995}
2996
2997/// cvtStExtTWriteBackReg - Convert parsed operands to MCInst.
2998/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2999/// when they refer multiple MIOperands inside a single one.
3000bool ARMAsmParser::
3001cvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
3002                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3003  // Create a writeback register dummy placeholder.
3004  Inst.addOperand(MCOperand::CreateImm(0));
3005  // Rt
3006  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3007  // addr
3008  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
3009  // offset
3010  ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2);
3011  // pred
3012  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3013  return true;
3014}
3015
3016/// cvtLdrdPre - Convert parsed operands to MCInst.
3017/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3018/// when they refer multiple MIOperands inside a single one.
3019bool ARMAsmParser::
3020cvtLdrdPre(MCInst &Inst, unsigned Opcode,
3021           const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3022  // Rt, Rt2
3023  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3024  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
3025  // Create a writeback register dummy placeholder.
3026  Inst.addOperand(MCOperand::CreateImm(0));
3027  // addr
3028  ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3);
3029  // pred
3030  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3031  return true;
3032}
3033
3034/// cvtStrdPre - Convert parsed operands to MCInst.
3035/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3036/// when they refer multiple MIOperands inside a single one.
3037bool ARMAsmParser::
3038cvtStrdPre(MCInst &Inst, unsigned Opcode,
3039           const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3040  // Create a writeback register dummy placeholder.
3041  Inst.addOperand(MCOperand::CreateImm(0));
3042  // Rt, Rt2
3043  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3044  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
3045  // addr
3046  ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3);
3047  // pred
3048  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3049  return true;
3050}
3051
3052/// cvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
3053/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3054/// when they refer multiple MIOperands inside a single one.
3055bool ARMAsmParser::
3056cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
3057                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3058  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3059  // Create a writeback register dummy placeholder.
3060  Inst.addOperand(MCOperand::CreateImm(0));
3061  ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3);
3062  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3063  return true;
3064}
3065
3066/// cvtThumbMultiple- Convert parsed operands to MCInst.
3067/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3068/// when they refer multiple MIOperands inside a single one.
3069bool ARMAsmParser::
3070cvtThumbMultiply(MCInst &Inst, unsigned Opcode,
3071           const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3072  // The second source operand must be the same register as the destination
3073  // operand.
3074  if (Operands.size() == 6 &&
3075      (((ARMOperand*)Operands[3])->getReg() !=
3076       ((ARMOperand*)Operands[5])->getReg()) &&
3077      (((ARMOperand*)Operands[3])->getReg() !=
3078       ((ARMOperand*)Operands[4])->getReg())) {
3079    Error(Operands[3]->getStartLoc(),
3080          "destination register must match source register");
3081    return false;
3082  }
3083  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
3084  ((ARMOperand*)Operands[1])->addCCOutOperands(Inst, 1);
3085  ((ARMOperand*)Operands[4])->addRegOperands(Inst, 1);
3086  // If we have a three-operand form, use that, else the second source operand
3087  // is just the destination operand again.
3088  if (Operands.size() == 6)
3089    ((ARMOperand*)Operands[5])->addRegOperands(Inst, 1);
3090  else
3091    Inst.addOperand(Inst.getOperand(0));
3092  ((ARMOperand*)Operands[2])->addCondCodeOperands(Inst, 2);
3093
3094  return true;
3095}
3096
3097/// Parse an ARM memory expression, return false if successful else return true
3098/// or an error.  The first token must be a '[' when called.
3099bool ARMAsmParser::
3100parseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3101  SMLoc S, E;
3102  assert(Parser.getTok().is(AsmToken::LBrac) &&
3103         "Token is not a Left Bracket");
3104  S = Parser.getTok().getLoc();
3105  Parser.Lex(); // Eat left bracket token.
3106
3107  const AsmToken &BaseRegTok = Parser.getTok();
3108  int BaseRegNum = tryParseRegister();
3109  if (BaseRegNum == -1)
3110    return Error(BaseRegTok.getLoc(), "register expected");
3111
3112  // The next token must either be a comma or a closing bracket.
3113  const AsmToken &Tok = Parser.getTok();
3114  if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac))
3115    return Error(Tok.getLoc(), "malformed memory operand");
3116
3117  if (Tok.is(AsmToken::RBrac)) {
3118    E = Tok.getLoc();
3119    Parser.Lex(); // Eat right bracket token.
3120
3121    Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0, ARM_AM::no_shift,
3122                                             0, 0, false, S, E));
3123
3124    // If there's a pre-indexing writeback marker, '!', just add it as a token
3125    // operand. It's rather odd, but syntactically valid.
3126    if (Parser.getTok().is(AsmToken::Exclaim)) {
3127      Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
3128      Parser.Lex(); // Eat the '!'.
3129    }
3130
3131    return false;
3132  }
3133
3134  assert(Tok.is(AsmToken::Comma) && "Lost comma in memory operand?!");
3135  Parser.Lex(); // Eat the comma.
3136
3137  // If we have a ':', it's an alignment specifier.
3138  if (Parser.getTok().is(AsmToken::Colon)) {
3139    Parser.Lex(); // Eat the ':'.
3140    E = Parser.getTok().getLoc();
3141
3142    const MCExpr *Expr;
3143    if (getParser().ParseExpression(Expr))
3144     return true;
3145
3146    // The expression has to be a constant. Memory references with relocations
3147    // don't come through here, as they use the <label> forms of the relevant
3148    // instructions.
3149    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
3150    if (!CE)
3151      return Error (E, "constant expression expected");
3152
3153    unsigned Align = 0;
3154    switch (CE->getValue()) {
3155    default:
3156      return Error(E, "alignment specifier must be 64, 128, or 256 bits");
3157    case 64:  Align = 8; break;
3158    case 128: Align = 16; break;
3159    case 256: Align = 32; break;
3160    }
3161
3162    // Now we should have the closing ']'
3163    E = Parser.getTok().getLoc();
3164    if (Parser.getTok().isNot(AsmToken::RBrac))
3165      return Error(E, "']' expected");
3166    Parser.Lex(); // Eat right bracket token.
3167
3168    // Don't worry about range checking the value here. That's handled by
3169    // the is*() predicates.
3170    Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0,
3171                                             ARM_AM::no_shift, 0, Align,
3172                                             false, S, E));
3173
3174    // If there's a pre-indexing writeback marker, '!', just add it as a token
3175    // operand.
3176    if (Parser.getTok().is(AsmToken::Exclaim)) {
3177      Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
3178      Parser.Lex(); // Eat the '!'.
3179    }
3180
3181    return false;
3182  }
3183
3184  // If we have a '#', it's an immediate offset, else assume it's a register
3185  // offset.
3186  if (Parser.getTok().is(AsmToken::Hash)) {
3187    Parser.Lex(); // Eat the '#'.
3188    E = Parser.getTok().getLoc();
3189
3190    bool isNegative = getParser().getTok().is(AsmToken::Minus);
3191    const MCExpr *Offset;
3192    if (getParser().ParseExpression(Offset))
3193     return true;
3194
3195    // The expression has to be a constant. Memory references with relocations
3196    // don't come through here, as they use the <label> forms of the relevant
3197    // instructions.
3198    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset);
3199    if (!CE)
3200      return Error (E, "constant expression expected");
3201
3202    // If the constant was #-0, represent it as INT32_MIN.
3203    int32_t Val = CE->getValue();
3204    if (isNegative && Val == 0)
3205      CE = MCConstantExpr::Create(INT32_MIN, getContext());
3206
3207    // Now we should have the closing ']'
3208    E = Parser.getTok().getLoc();
3209    if (Parser.getTok().isNot(AsmToken::RBrac))
3210      return Error(E, "']' expected");
3211    Parser.Lex(); // Eat right bracket token.
3212
3213    // Don't worry about range checking the value here. That's handled by
3214    // the is*() predicates.
3215    Operands.push_back(ARMOperand::CreateMem(BaseRegNum, CE, 0,
3216                                             ARM_AM::no_shift, 0, 0,
3217                                             false, S, E));
3218
3219    // If there's a pre-indexing writeback marker, '!', just add it as a token
3220    // operand.
3221    if (Parser.getTok().is(AsmToken::Exclaim)) {
3222      Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
3223      Parser.Lex(); // Eat the '!'.
3224    }
3225
3226    return false;
3227  }
3228
3229  // The register offset is optionally preceded by a '+' or '-'
3230  bool isNegative = false;
3231  if (Parser.getTok().is(AsmToken::Minus)) {
3232    isNegative = true;
3233    Parser.Lex(); // Eat the '-'.
3234  } else if (Parser.getTok().is(AsmToken::Plus)) {
3235    // Nothing to do.
3236    Parser.Lex(); // Eat the '+'.
3237  }
3238
3239  E = Parser.getTok().getLoc();
3240  int OffsetRegNum = tryParseRegister();
3241  if (OffsetRegNum == -1)
3242    return Error(E, "register expected");
3243
3244  // If there's a shift operator, handle it.
3245  ARM_AM::ShiftOpc ShiftType = ARM_AM::no_shift;
3246  unsigned ShiftImm = 0;
3247  if (Parser.getTok().is(AsmToken::Comma)) {
3248    Parser.Lex(); // Eat the ','.
3249    if (parseMemRegOffsetShift(ShiftType, ShiftImm))
3250      return true;
3251  }
3252
3253  // Now we should have the closing ']'
3254  E = Parser.getTok().getLoc();
3255  if (Parser.getTok().isNot(AsmToken::RBrac))
3256    return Error(E, "']' expected");
3257  Parser.Lex(); // Eat right bracket token.
3258
3259  Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, OffsetRegNum,
3260                                           ShiftType, ShiftImm, 0, isNegative,
3261                                           S, E));
3262
3263  // If there's a pre-indexing writeback marker, '!', just add it as a token
3264  // operand.
3265  if (Parser.getTok().is(AsmToken::Exclaim)) {
3266    Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
3267    Parser.Lex(); // Eat the '!'.
3268  }
3269
3270  return false;
3271}
3272
3273/// parseMemRegOffsetShift - one of these two:
3274///   ( lsl | lsr | asr | ror ) , # shift_amount
3275///   rrx
3276/// return true if it parses a shift otherwise it returns false.
3277bool ARMAsmParser::parseMemRegOffsetShift(ARM_AM::ShiftOpc &St,
3278                                          unsigned &Amount) {
3279  SMLoc Loc = Parser.getTok().getLoc();
3280  const AsmToken &Tok = Parser.getTok();
3281  if (Tok.isNot(AsmToken::Identifier))
3282    return true;
3283  StringRef ShiftName = Tok.getString();
3284  if (ShiftName == "lsl" || ShiftName == "LSL")
3285    St = ARM_AM::lsl;
3286  else if (ShiftName == "lsr" || ShiftName == "LSR")
3287    St = ARM_AM::lsr;
3288  else if (ShiftName == "asr" || ShiftName == "ASR")
3289    St = ARM_AM::asr;
3290  else if (ShiftName == "ror" || ShiftName == "ROR")
3291    St = ARM_AM::ror;
3292  else if (ShiftName == "rrx" || ShiftName == "RRX")
3293    St = ARM_AM::rrx;
3294  else
3295    return Error(Loc, "illegal shift operator");
3296  Parser.Lex(); // Eat shift type token.
3297
3298  // rrx stands alone.
3299  Amount = 0;
3300  if (St != ARM_AM::rrx) {
3301    Loc = Parser.getTok().getLoc();
3302    // A '#' and a shift amount.
3303    const AsmToken &HashTok = Parser.getTok();
3304    if (HashTok.isNot(AsmToken::Hash))
3305      return Error(HashTok.getLoc(), "'#' expected");
3306    Parser.Lex(); // Eat hash token.
3307
3308    const MCExpr *Expr;
3309    if (getParser().ParseExpression(Expr))
3310      return true;
3311    // Range check the immediate.
3312    // lsl, ror: 0 <= imm <= 31
3313    // lsr, asr: 0 <= imm <= 32
3314    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
3315    if (!CE)
3316      return Error(Loc, "shift amount must be an immediate");
3317    int64_t Imm = CE->getValue();
3318    if (Imm < 0 ||
3319        ((St == ARM_AM::lsl || St == ARM_AM::ror) && Imm > 31) ||
3320        ((St == ARM_AM::lsr || St == ARM_AM::asr) && Imm > 32))
3321      return Error(Loc, "immediate shift value out of range");
3322    Amount = Imm;
3323  }
3324
3325  return false;
3326}
3327
3328/// parseFPImm - A floating point immediate expression operand.
3329ARMAsmParser::OperandMatchResultTy ARMAsmParser::
3330parseFPImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3331  SMLoc S = Parser.getTok().getLoc();
3332
3333  if (Parser.getTok().isNot(AsmToken::Hash))
3334    return MatchOperand_NoMatch;
3335  Parser.Lex(); // Eat the '#'.
3336
3337  // Handle negation, as that still comes through as a separate token.
3338  bool isNegative = false;
3339  if (Parser.getTok().is(AsmToken::Minus)) {
3340    isNegative = true;
3341    Parser.Lex();
3342  }
3343  const AsmToken &Tok = Parser.getTok();
3344  if (Tok.is(AsmToken::Real)) {
3345    APFloat RealVal(APFloat::IEEEdouble, Tok.getString());
3346    uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
3347    // If we had a '-' in front, toggle the sign bit.
3348    IntVal ^= (uint64_t)isNegative << 63;
3349    int Val = ARM_AM::getFP64Imm(APInt(64, IntVal));
3350    Parser.Lex(); // Eat the token.
3351    if (Val == -1) {
3352      TokError("floating point value out of range");
3353      return MatchOperand_ParseFail;
3354    }
3355    Operands.push_back(ARMOperand::CreateFPImm(Val, S, getContext()));
3356    return MatchOperand_Success;
3357  }
3358  if (Tok.is(AsmToken::Integer)) {
3359    int64_t Val = Tok.getIntVal();
3360    Parser.Lex(); // Eat the token.
3361    if (Val > 255 || Val < 0) {
3362      TokError("encoded floating point value out of range");
3363      return MatchOperand_ParseFail;
3364    }
3365    Operands.push_back(ARMOperand::CreateFPImm(Val, S, getContext()));
3366    return MatchOperand_Success;
3367  }
3368
3369  TokError("invalid floating point immediate");
3370  return MatchOperand_ParseFail;
3371}
3372/// Parse a arm instruction operand.  For now this parses the operand regardless
3373/// of the mnemonic.
3374bool ARMAsmParser::parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
3375                                StringRef Mnemonic) {
3376  SMLoc S, E;
3377
3378  // Check if the current operand has a custom associated parser, if so, try to
3379  // custom parse the operand, or fallback to the general approach.
3380  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
3381  if (ResTy == MatchOperand_Success)
3382    return false;
3383  // If there wasn't a custom match, try the generic matcher below. Otherwise,
3384  // there was a match, but an error occurred, in which case, just return that
3385  // the operand parsing failed.
3386  if (ResTy == MatchOperand_ParseFail)
3387    return true;
3388
3389  switch (getLexer().getKind()) {
3390  default:
3391    Error(Parser.getTok().getLoc(), "unexpected token in operand");
3392    return true;
3393  case AsmToken::Identifier: {
3394    // If this is VMRS, check for the apsr_nzcv operand.
3395    if (!tryParseRegisterWithWriteBack(Operands))
3396      return false;
3397    int Res = tryParseShiftRegister(Operands);
3398    if (Res == 0) // success
3399      return false;
3400    else if (Res == -1) // irrecoverable error
3401      return true;
3402    if (Mnemonic == "vmrs" && Parser.getTok().getString() == "apsr_nzcv") {
3403      S = Parser.getTok().getLoc();
3404      Parser.Lex();
3405      Operands.push_back(ARMOperand::CreateToken("apsr_nzcv", S));
3406      return false;
3407    }
3408
3409    // Fall though for the Identifier case that is not a register or a
3410    // special name.
3411  }
3412  case AsmToken::Integer: // things like 1f and 2b as a branch targets
3413  case AsmToken::Dot: {   // . as a branch target
3414    // This was not a register so parse other operands that start with an
3415    // identifier (like labels) as expressions and create them as immediates.
3416    const MCExpr *IdVal;
3417    S = Parser.getTok().getLoc();
3418    if (getParser().ParseExpression(IdVal))
3419      return true;
3420    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3421    Operands.push_back(ARMOperand::CreateImm(IdVal, S, E));
3422    return false;
3423  }
3424  case AsmToken::LBrac:
3425    return parseMemory(Operands);
3426  case AsmToken::LCurly:
3427    return parseRegisterList(Operands);
3428  case AsmToken::Hash: {
3429    // #42 -> immediate.
3430    // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate
3431    S = Parser.getTok().getLoc();
3432    Parser.Lex();
3433    bool isNegative = Parser.getTok().is(AsmToken::Minus);
3434    const MCExpr *ImmVal;
3435    if (getParser().ParseExpression(ImmVal))
3436      return true;
3437    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ImmVal);
3438    if (!CE) {
3439      Error(S, "constant expression expected");
3440      return MatchOperand_ParseFail;
3441    }
3442    int32_t Val = CE->getValue();
3443    if (isNegative && Val == 0)
3444      ImmVal = MCConstantExpr::Create(INT32_MIN, getContext());
3445    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3446    Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E));
3447    return false;
3448  }
3449  case AsmToken::Colon: {
3450    // ":lower16:" and ":upper16:" expression prefixes
3451    // FIXME: Check it's an expression prefix,
3452    // e.g. (FOO - :lower16:BAR) isn't legal.
3453    ARMMCExpr::VariantKind RefKind;
3454    if (parsePrefix(RefKind))
3455      return true;
3456
3457    const MCExpr *SubExprVal;
3458    if (getParser().ParseExpression(SubExprVal))
3459      return true;
3460
3461    const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal,
3462                                                   getContext());
3463    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3464    Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E));
3465    return false;
3466  }
3467  }
3468}
3469
3470// parsePrefix - Parse ARM 16-bit relocations expression prefix, i.e.
3471//  :lower16: and :upper16:.
3472bool ARMAsmParser::parsePrefix(ARMMCExpr::VariantKind &RefKind) {
3473  RefKind = ARMMCExpr::VK_ARM_None;
3474
3475  // :lower16: and :upper16: modifiers
3476  assert(getLexer().is(AsmToken::Colon) && "expected a :");
3477  Parser.Lex(); // Eat ':'
3478
3479  if (getLexer().isNot(AsmToken::Identifier)) {
3480    Error(Parser.getTok().getLoc(), "expected prefix identifier in operand");
3481    return true;
3482  }
3483
3484  StringRef IDVal = Parser.getTok().getIdentifier();
3485  if (IDVal == "lower16") {
3486    RefKind = ARMMCExpr::VK_ARM_LO16;
3487  } else if (IDVal == "upper16") {
3488    RefKind = ARMMCExpr::VK_ARM_HI16;
3489  } else {
3490    Error(Parser.getTok().getLoc(), "unexpected prefix in operand");
3491    return true;
3492  }
3493  Parser.Lex();
3494
3495  if (getLexer().isNot(AsmToken::Colon)) {
3496    Error(Parser.getTok().getLoc(), "unexpected token after prefix");
3497    return true;
3498  }
3499  Parser.Lex(); // Eat the last ':'
3500  return false;
3501}
3502
3503/// \brief Given a mnemonic, split out possible predication code and carry
3504/// setting letters to form a canonical mnemonic and flags.
3505//
3506// FIXME: Would be nice to autogen this.
3507// FIXME: This is a bit of a maze of special cases.
3508StringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic,
3509                                      unsigned &PredicationCode,
3510                                      bool &CarrySetting,
3511                                      unsigned &ProcessorIMod,
3512                                      StringRef &ITMask) {
3513  PredicationCode = ARMCC::AL;
3514  CarrySetting = false;
3515  ProcessorIMod = 0;
3516
3517  // Ignore some mnemonics we know aren't predicated forms.
3518  //
3519  // FIXME: Would be nice to autogen this.
3520  if ((Mnemonic == "movs" && isThumb()) ||
3521      Mnemonic == "teq"   || Mnemonic == "vceq"   || Mnemonic == "svc"   ||
3522      Mnemonic == "mls"   || Mnemonic == "smmls"  || Mnemonic == "vcls"  ||
3523      Mnemonic == "vmls"  || Mnemonic == "vnmls"  || Mnemonic == "vacge" ||
3524      Mnemonic == "vcge"  || Mnemonic == "vclt"   || Mnemonic == "vacgt" ||
3525      Mnemonic == "vcgt"  || Mnemonic == "vcle"   || Mnemonic == "smlal" ||
3526      Mnemonic == "umaal" || Mnemonic == "umlal"  || Mnemonic == "vabal" ||
3527      Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal")
3528    return Mnemonic;
3529
3530  // First, split out any predication code. Ignore mnemonics we know aren't
3531  // predicated but do have a carry-set and so weren't caught above.
3532  if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" &&
3533      Mnemonic != "muls" && Mnemonic != "smlals" && Mnemonic != "smulls" &&
3534      Mnemonic != "umlals" && Mnemonic != "umulls" && Mnemonic != "lsls" &&
3535      Mnemonic != "sbcs" && Mnemonic != "rscs") {
3536    unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2))
3537      .Case("eq", ARMCC::EQ)
3538      .Case("ne", ARMCC::NE)
3539      .Case("hs", ARMCC::HS)
3540      .Case("cs", ARMCC::HS)
3541      .Case("lo", ARMCC::LO)
3542      .Case("cc", ARMCC::LO)
3543      .Case("mi", ARMCC::MI)
3544      .Case("pl", ARMCC::PL)
3545      .Case("vs", ARMCC::VS)
3546      .Case("vc", ARMCC::VC)
3547      .Case("hi", ARMCC::HI)
3548      .Case("ls", ARMCC::LS)
3549      .Case("ge", ARMCC::GE)
3550      .Case("lt", ARMCC::LT)
3551      .Case("gt", ARMCC::GT)
3552      .Case("le", ARMCC::LE)
3553      .Case("al", ARMCC::AL)
3554      .Default(~0U);
3555    if (CC != ~0U) {
3556      Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2);
3557      PredicationCode = CC;
3558    }
3559  }
3560
3561  // Next, determine if we have a carry setting bit. We explicitly ignore all
3562  // the instructions we know end in 's'.
3563  if (Mnemonic.endswith("s") &&
3564      !(Mnemonic == "cps" || Mnemonic == "mls" ||
3565        Mnemonic == "mrs" || Mnemonic == "smmls" || Mnemonic == "vabs" ||
3566        Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vmrs" ||
3567        Mnemonic == "vnmls" || Mnemonic == "vqabs" || Mnemonic == "vrecps" ||
3568        Mnemonic == "vrsqrts" || Mnemonic == "srs" ||
3569        (Mnemonic == "movs" && isThumb()))) {
3570    Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1);
3571    CarrySetting = true;
3572  }
3573
3574  // The "cps" instruction can have a interrupt mode operand which is glued into
3575  // the mnemonic. Check if this is the case, split it and parse the imod op
3576  if (Mnemonic.startswith("cps")) {
3577    // Split out any imod code.
3578    unsigned IMod =
3579      StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2))
3580      .Case("ie", ARM_PROC::IE)
3581      .Case("id", ARM_PROC::ID)
3582      .Default(~0U);
3583    if (IMod != ~0U) {
3584      Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2);
3585      ProcessorIMod = IMod;
3586    }
3587  }
3588
3589  // The "it" instruction has the condition mask on the end of the mnemonic.
3590  if (Mnemonic.startswith("it")) {
3591    ITMask = Mnemonic.slice(2, Mnemonic.size());
3592    Mnemonic = Mnemonic.slice(0, 2);
3593  }
3594
3595  return Mnemonic;
3596}
3597
3598/// \brief Given a canonical mnemonic, determine if the instruction ever allows
3599/// inclusion of carry set or predication code operands.
3600//
3601// FIXME: It would be nice to autogen this.
3602void ARMAsmParser::
3603getMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
3604                      bool &CanAcceptPredicationCode) {
3605  if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" ||
3606      Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" ||
3607      Mnemonic == "add" || Mnemonic == "adc" ||
3608      Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" ||
3609      Mnemonic == "orr" || Mnemonic == "mvn" ||
3610      Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" ||
3611      Mnemonic == "sbc" || Mnemonic == "eor" || Mnemonic == "neg" ||
3612      (!isThumb() && (Mnemonic == "smull" || Mnemonic == "mov" ||
3613                      Mnemonic == "mla" || Mnemonic == "smlal" ||
3614                      Mnemonic == "umlal" || Mnemonic == "umull"))) {
3615    CanAcceptCarrySet = true;
3616  } else
3617    CanAcceptCarrySet = false;
3618
3619  if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" ||
3620      Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" ||
3621      Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" ||
3622      Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" ||
3623      Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "setend" ||
3624      (Mnemonic == "clrex" && !isThumb()) ||
3625      (Mnemonic == "nop" && isThumbOne()) ||
3626      ((Mnemonic == "pld" || Mnemonic == "pli" || Mnemonic == "pldw" ||
3627        Mnemonic == "ldc2" || Mnemonic == "ldc2l" ||
3628        Mnemonic == "stc2" || Mnemonic == "stc2l") && !isThumb()) ||
3629      ((Mnemonic.startswith("rfe") || Mnemonic.startswith("srs")) &&
3630       !isThumb()) ||
3631      Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumbOne())) {
3632    CanAcceptPredicationCode = false;
3633  } else
3634    CanAcceptPredicationCode = true;
3635
3636  if (isThumb()) {
3637    if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" ||
3638        Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp")
3639      CanAcceptPredicationCode = false;
3640  }
3641}
3642
3643bool ARMAsmParser::shouldOmitCCOutOperand(StringRef Mnemonic,
3644                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3645  // FIXME: This is all horribly hacky. We really need a better way to deal
3646  // with optional operands like this in the matcher table.
3647
3648  // The 'mov' mnemonic is special. One variant has a cc_out operand, while
3649  // another does not. Specifically, the MOVW instruction does not. So we
3650  // special case it here and remove the defaulted (non-setting) cc_out
3651  // operand if that's the instruction we're trying to match.
3652  //
3653  // We do this as post-processing of the explicit operands rather than just
3654  // conditionally adding the cc_out in the first place because we need
3655  // to check the type of the parsed immediate operand.
3656  if (Mnemonic == "mov" && Operands.size() > 4 && !isThumb() &&
3657      !static_cast<ARMOperand*>(Operands[4])->isARMSOImm() &&
3658      static_cast<ARMOperand*>(Operands[4])->isImm0_65535Expr() &&
3659      static_cast<ARMOperand*>(Operands[1])->getReg() == 0)
3660    return true;
3661
3662  // Register-register 'add' for thumb does not have a cc_out operand
3663  // when there are only two register operands.
3664  if (isThumb() && Mnemonic == "add" && Operands.size() == 5 &&
3665      static_cast<ARMOperand*>(Operands[3])->isReg() &&
3666      static_cast<ARMOperand*>(Operands[4])->isReg() &&
3667      static_cast<ARMOperand*>(Operands[1])->getReg() == 0)
3668    return true;
3669  // Register-register 'add' for thumb does not have a cc_out operand
3670  // when it's an ADD Rdm, SP, {Rdm|#imm0_255} instruction. We do
3671  // have to check the immediate range here since Thumb2 has a variant
3672  // that can handle a different range and has a cc_out operand.
3673  if (((isThumb() && Mnemonic == "add") ||
3674       (isThumbTwo() && Mnemonic == "sub")) &&
3675      Operands.size() == 6 &&
3676      static_cast<ARMOperand*>(Operands[3])->isReg() &&
3677      static_cast<ARMOperand*>(Operands[4])->isReg() &&
3678      static_cast<ARMOperand*>(Operands[4])->getReg() == ARM::SP &&
3679      static_cast<ARMOperand*>(Operands[1])->getReg() == 0 &&
3680      (static_cast<ARMOperand*>(Operands[5])->isReg() ||
3681       static_cast<ARMOperand*>(Operands[5])->isImm0_1020s4()))
3682    return true;
3683  // For Thumb2, add/sub immediate does not have a cc_out operand for the
3684  // imm0_4095 variant. That's the least-preferred variant when
3685  // selecting via the generic "add" mnemonic, so to know that we
3686  // should remove the cc_out operand, we have to explicitly check that
3687  // it's not one of the other variants. Ugh.
3688  if (isThumbTwo() && (Mnemonic == "add" || Mnemonic == "sub") &&
3689      Operands.size() == 6 &&
3690      static_cast<ARMOperand*>(Operands[3])->isReg() &&
3691      static_cast<ARMOperand*>(Operands[4])->isReg() &&
3692      static_cast<ARMOperand*>(Operands[5])->isImm()) {
3693    // Nest conditions rather than one big 'if' statement for readability.
3694    //
3695    // If either register is a high reg, it's either one of the SP
3696    // variants (handled above) or a 32-bit encoding, so we just
3697    // check against T3.
3698    if ((!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) ||
3699         !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg())) &&
3700        static_cast<ARMOperand*>(Operands[5])->isT2SOImm())
3701      return false;
3702    // If both registers are low, we're in an IT block, and the immediate is
3703    // in range, we should use encoding T1 instead, which has a cc_out.
3704    if (inITBlock() &&
3705        isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) &&
3706        isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) &&
3707        static_cast<ARMOperand*>(Operands[5])->isImm0_7())
3708      return false;
3709
3710    // Otherwise, we use encoding T4, which does not have a cc_out
3711    // operand.
3712    return true;
3713  }
3714
3715  // The thumb2 multiply instruction doesn't have a CCOut register, so
3716  // if we have a "mul" mnemonic in Thumb mode, check if we'll be able to
3717  // use the 16-bit encoding or not.
3718  if (isThumbTwo() && Mnemonic == "mul" && Operands.size() == 6 &&
3719      static_cast<ARMOperand*>(Operands[1])->getReg() == 0 &&
3720      static_cast<ARMOperand*>(Operands[3])->isReg() &&
3721      static_cast<ARMOperand*>(Operands[4])->isReg() &&
3722      static_cast<ARMOperand*>(Operands[5])->isReg() &&
3723      // If the registers aren't low regs, the destination reg isn't the
3724      // same as one of the source regs, or the cc_out operand is zero
3725      // outside of an IT block, we have to use the 32-bit encoding, so
3726      // remove the cc_out operand.
3727      (!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) ||
3728       !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) ||
3729       !inITBlock() ||
3730       (static_cast<ARMOperand*>(Operands[3])->getReg() !=
3731        static_cast<ARMOperand*>(Operands[5])->getReg() &&
3732        static_cast<ARMOperand*>(Operands[3])->getReg() !=
3733        static_cast<ARMOperand*>(Operands[4])->getReg())))
3734    return true;
3735
3736
3737
3738  // Register-register 'add/sub' for thumb does not have a cc_out operand
3739  // when it's an ADD/SUB SP, #imm. Be lenient on count since there's also
3740  // the "add/sub SP, SP, #imm" version. If the follow-up operands aren't
3741  // right, this will result in better diagnostics (which operand is off)
3742  // anyway.
3743  if (isThumb() && (Mnemonic == "add" || Mnemonic == "sub") &&
3744      (Operands.size() == 5 || Operands.size() == 6) &&
3745      static_cast<ARMOperand*>(Operands[3])->isReg() &&
3746      static_cast<ARMOperand*>(Operands[3])->getReg() == ARM::SP &&
3747      static_cast<ARMOperand*>(Operands[1])->getReg() == 0)
3748    return true;
3749
3750  return false;
3751}
3752
3753/// Parse an arm instruction mnemonic followed by its operands.
3754bool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc,
3755                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3756  // Create the leading tokens for the mnemonic, split by '.' characters.
3757  size_t Start = 0, Next = Name.find('.');
3758  StringRef Mnemonic = Name.slice(Start, Next);
3759
3760  // Split out the predication code and carry setting flag from the mnemonic.
3761  unsigned PredicationCode;
3762  unsigned ProcessorIMod;
3763  bool CarrySetting;
3764  StringRef ITMask;
3765  Mnemonic = splitMnemonic(Mnemonic, PredicationCode, CarrySetting,
3766                           ProcessorIMod, ITMask);
3767
3768  // In Thumb1, only the branch (B) instruction can be predicated.
3769  if (isThumbOne() && PredicationCode != ARMCC::AL && Mnemonic != "b") {
3770    Parser.EatToEndOfStatement();
3771    return Error(NameLoc, "conditional execution not supported in Thumb1");
3772  }
3773
3774  Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc));
3775
3776  // Handle the IT instruction ITMask. Convert it to a bitmask. This
3777  // is the mask as it will be for the IT encoding if the conditional
3778  // encoding has a '1' as it's bit0 (i.e. 't' ==> '1'). In the case
3779  // where the conditional bit0 is zero, the instruction post-processing
3780  // will adjust the mask accordingly.
3781  if (Mnemonic == "it") {
3782    SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + 2);
3783    if (ITMask.size() > 3) {
3784      Parser.EatToEndOfStatement();
3785      return Error(Loc, "too many conditions on IT instruction");
3786    }
3787    unsigned Mask = 8;
3788    for (unsigned i = ITMask.size(); i != 0; --i) {
3789      char pos = ITMask[i - 1];
3790      if (pos != 't' && pos != 'e') {
3791        Parser.EatToEndOfStatement();
3792        return Error(Loc, "illegal IT block condition mask '" + ITMask + "'");
3793      }
3794      Mask >>= 1;
3795      if (ITMask[i - 1] == 't')
3796        Mask |= 8;
3797    }
3798    Operands.push_back(ARMOperand::CreateITMask(Mask, Loc));
3799  }
3800
3801  // FIXME: This is all a pretty gross hack. We should automatically handle
3802  // optional operands like this via tblgen.
3803
3804  // Next, add the CCOut and ConditionCode operands, if needed.
3805  //
3806  // For mnemonics which can ever incorporate a carry setting bit or predication
3807  // code, our matching model involves us always generating CCOut and
3808  // ConditionCode operands to match the mnemonic "as written" and then we let
3809  // the matcher deal with finding the right instruction or generating an
3810  // appropriate error.
3811  bool CanAcceptCarrySet, CanAcceptPredicationCode;
3812  getMnemonicAcceptInfo(Mnemonic, CanAcceptCarrySet, CanAcceptPredicationCode);
3813
3814  // If we had a carry-set on an instruction that can't do that, issue an
3815  // error.
3816  if (!CanAcceptCarrySet && CarrySetting) {
3817    Parser.EatToEndOfStatement();
3818    return Error(NameLoc, "instruction '" + Mnemonic +
3819                 "' can not set flags, but 's' suffix specified");
3820  }
3821  // If we had a predication code on an instruction that can't do that, issue an
3822  // error.
3823  if (!CanAcceptPredicationCode && PredicationCode != ARMCC::AL) {
3824    Parser.EatToEndOfStatement();
3825    return Error(NameLoc, "instruction '" + Mnemonic +
3826                 "' is not predicable, but condition code specified");
3827  }
3828
3829  // Add the carry setting operand, if necessary.
3830  if (CanAcceptCarrySet) {
3831    SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size());
3832    Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0,
3833                                               Loc));
3834  }
3835
3836  // Add the predication code operand, if necessary.
3837  if (CanAcceptPredicationCode) {
3838    SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size() +
3839                                      CarrySetting);
3840    Operands.push_back(ARMOperand::CreateCondCode(
3841                         ARMCC::CondCodes(PredicationCode), Loc));
3842  }
3843
3844  // Add the processor imod operand, if necessary.
3845  if (ProcessorIMod) {
3846    Operands.push_back(ARMOperand::CreateImm(
3847          MCConstantExpr::Create(ProcessorIMod, getContext()),
3848                                 NameLoc, NameLoc));
3849  }
3850
3851  // Add the remaining tokens in the mnemonic.
3852  while (Next != StringRef::npos) {
3853    Start = Next;
3854    Next = Name.find('.', Start + 1);
3855    StringRef ExtraToken = Name.slice(Start, Next);
3856
3857    // For now, we're only parsing Thumb1 (for the most part), so
3858    // just ignore ".n" qualifiers. We'll use them to restrict
3859    // matching when we do Thumb2.
3860    if (ExtraToken != ".n") {
3861      SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Start);
3862      Operands.push_back(ARMOperand::CreateToken(ExtraToken, Loc));
3863    }
3864  }
3865
3866  // Read the remaining operands.
3867  if (getLexer().isNot(AsmToken::EndOfStatement)) {
3868    // Read the first operand.
3869    if (parseOperand(Operands, Mnemonic)) {
3870      Parser.EatToEndOfStatement();
3871      return true;
3872    }
3873
3874    while (getLexer().is(AsmToken::Comma)) {
3875      Parser.Lex();  // Eat the comma.
3876
3877      // Parse and remember the operand.
3878      if (parseOperand(Operands, Mnemonic)) {
3879        Parser.EatToEndOfStatement();
3880        return true;
3881      }
3882    }
3883  }
3884
3885  if (getLexer().isNot(AsmToken::EndOfStatement)) {
3886    SMLoc Loc = getLexer().getLoc();
3887    Parser.EatToEndOfStatement();
3888    return Error(Loc, "unexpected token in argument list");
3889  }
3890
3891  Parser.Lex(); // Consume the EndOfStatement
3892
3893  // Some instructions, mostly Thumb, have forms for the same mnemonic that
3894  // do and don't have a cc_out optional-def operand. With some spot-checks
3895  // of the operand list, we can figure out which variant we're trying to
3896  // parse and adjust accordingly before actually matching. We shouldn't ever
3897  // try to remove a cc_out operand that was explicitly set on the the
3898  // mnemonic, of course (CarrySetting == true). Reason number #317 the
3899  // table driven matcher doesn't fit well with the ARM instruction set.
3900  if (!CarrySetting && shouldOmitCCOutOperand(Mnemonic, Operands)) {
3901    ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]);
3902    Operands.erase(Operands.begin() + 1);
3903    delete Op;
3904  }
3905
3906  // ARM mode 'blx' need special handling, as the register operand version
3907  // is predicable, but the label operand version is not. So, we can't rely
3908  // on the Mnemonic based checking to correctly figure out when to put
3909  // a k_CondCode operand in the list. If we're trying to match the label
3910  // version, remove the k_CondCode operand here.
3911  if (!isThumb() && Mnemonic == "blx" && Operands.size() == 3 &&
3912      static_cast<ARMOperand*>(Operands[2])->isImm()) {
3913    ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]);
3914    Operands.erase(Operands.begin() + 1);
3915    delete Op;
3916  }
3917
3918  // The vector-compare-to-zero instructions have a literal token "#0" at
3919  // the end that comes to here as an immediate operand. Convert it to a
3920  // token to play nicely with the matcher.
3921  if ((Mnemonic == "vceq" || Mnemonic == "vcge" || Mnemonic == "vcgt" ||
3922      Mnemonic == "vcle" || Mnemonic == "vclt") && Operands.size() == 6 &&
3923      static_cast<ARMOperand*>(Operands[5])->isImm()) {
3924    ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]);
3925    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
3926    if (CE && CE->getValue() == 0) {
3927      Operands.erase(Operands.begin() + 5);
3928      Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc()));
3929      delete Op;
3930    }
3931  }
3932  // VCMP{E} does the same thing, but with a different operand count.
3933  if ((Mnemonic == "vcmp" || Mnemonic == "vcmpe") && Operands.size() == 5 &&
3934      static_cast<ARMOperand*>(Operands[4])->isImm()) {
3935    ARMOperand *Op = static_cast<ARMOperand*>(Operands[4]);
3936    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
3937    if (CE && CE->getValue() == 0) {
3938      Operands.erase(Operands.begin() + 4);
3939      Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc()));
3940      delete Op;
3941    }
3942  }
3943  // Similarly, the Thumb1 "RSB" instruction has a literal "#0" on the
3944  // end. Convert it to a token here.
3945  if (Mnemonic == "rsb" && isThumb() && Operands.size() == 6 &&
3946      static_cast<ARMOperand*>(Operands[5])->isImm()) {
3947    ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]);
3948    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
3949    if (CE && CE->getValue() == 0) {
3950      Operands.erase(Operands.begin() + 5);
3951      Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc()));
3952      delete Op;
3953    }
3954  }
3955
3956  return false;
3957}
3958
3959// Validate context-sensitive operand constraints.
3960
3961// return 'true' if register list contains non-low GPR registers,
3962// 'false' otherwise. If Reg is in the register list or is HiReg, set
3963// 'containsReg' to true.
3964static bool checkLowRegisterList(MCInst Inst, unsigned OpNo, unsigned Reg,
3965                                 unsigned HiReg, bool &containsReg) {
3966  containsReg = false;
3967  for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) {
3968    unsigned OpReg = Inst.getOperand(i).getReg();
3969    if (OpReg == Reg)
3970      containsReg = true;
3971    // Anything other than a low register isn't legal here.
3972    if (!isARMLowRegister(OpReg) && (!HiReg || OpReg != HiReg))
3973      return true;
3974  }
3975  return false;
3976}
3977
3978// Check if the specified regisgter is in the register list of the inst,
3979// starting at the indicated operand number.
3980static bool listContainsReg(MCInst &Inst, unsigned OpNo, unsigned Reg) {
3981  for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) {
3982    unsigned OpReg = Inst.getOperand(i).getReg();
3983    if (OpReg == Reg)
3984      return true;
3985  }
3986  return false;
3987}
3988
3989// FIXME: We would really prefer to have MCInstrInfo (the wrapper around
3990// the ARMInsts array) instead. Getting that here requires awkward
3991// API changes, though. Better way?
3992namespace llvm {
3993extern MCInstrDesc ARMInsts[];
3994}
3995static MCInstrDesc &getInstDesc(unsigned Opcode) {
3996  return ARMInsts[Opcode];
3997}
3998
3999// FIXME: We would really like to be able to tablegen'erate this.
4000bool ARMAsmParser::
4001validateInstruction(MCInst &Inst,
4002                    const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
4003  MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
4004  SMLoc Loc = Operands[0]->getStartLoc();
4005  // Check the IT block state first.
4006  // NOTE: In Thumb mode, the BKPT instruction has the interesting property of
4007  // being allowed in IT blocks, but not being predicable.  It just always
4008  // executes.
4009  if (inITBlock() && Inst.getOpcode() != ARM::tBKPT) {
4010    unsigned bit = 1;
4011    if (ITState.FirstCond)
4012      ITState.FirstCond = false;
4013    else
4014      bit = (ITState.Mask >> (5 - ITState.CurPosition)) & 1;
4015    // The instruction must be predicable.
4016    if (!MCID.isPredicable())
4017      return Error(Loc, "instructions in IT block must be predicable");
4018    unsigned Cond = Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm();
4019    unsigned ITCond = bit ? ITState.Cond :
4020      ARMCC::getOppositeCondition(ITState.Cond);
4021    if (Cond != ITCond) {
4022      // Find the condition code Operand to get its SMLoc information.
4023      SMLoc CondLoc;
4024      for (unsigned i = 1; i < Operands.size(); ++i)
4025        if (static_cast<ARMOperand*>(Operands[i])->isCondCode())
4026          CondLoc = Operands[i]->getStartLoc();
4027      return Error(CondLoc, "incorrect condition in IT block; got '" +
4028                   StringRef(ARMCondCodeToString(ARMCC::CondCodes(Cond))) +
4029                   "', but expected '" +
4030                   ARMCondCodeToString(ARMCC::CondCodes(ITCond)) + "'");
4031    }
4032  // Check for non-'al' condition codes outside of the IT block.
4033  } else if (isThumbTwo() && MCID.isPredicable() &&
4034             Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm() !=
4035             ARMCC::AL && Inst.getOpcode() != ARM::tB &&
4036             Inst.getOpcode() != ARM::t2B)
4037    return Error(Loc, "predicated instructions must be in IT block");
4038
4039  switch (Inst.getOpcode()) {
4040  case ARM::LDRD:
4041  case ARM::LDRD_PRE:
4042  case ARM::LDRD_POST:
4043  case ARM::LDREXD: {
4044    // Rt2 must be Rt + 1.
4045    unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg());
4046    unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg());
4047    if (Rt2 != Rt + 1)
4048      return Error(Operands[3]->getStartLoc(),
4049                   "destination operands must be sequential");
4050    return false;
4051  }
4052  case ARM::STRD: {
4053    // Rt2 must be Rt + 1.
4054    unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg());
4055    unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg());
4056    if (Rt2 != Rt + 1)
4057      return Error(Operands[3]->getStartLoc(),
4058                   "source operands must be sequential");
4059    return false;
4060  }
4061  case ARM::STRD_PRE:
4062  case ARM::STRD_POST:
4063  case ARM::STREXD: {
4064    // Rt2 must be Rt + 1.
4065    unsigned Rt = getARMRegisterNumbering(Inst.getOperand(1).getReg());
4066    unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(2).getReg());
4067    if (Rt2 != Rt + 1)
4068      return Error(Operands[3]->getStartLoc(),
4069                   "source operands must be sequential");
4070    return false;
4071  }
4072  case ARM::SBFX:
4073  case ARM::UBFX: {
4074    // width must be in range [1, 32-lsb]
4075    unsigned lsb = Inst.getOperand(2).getImm();
4076    unsigned widthm1 = Inst.getOperand(3).getImm();
4077    if (widthm1 >= 32 - lsb)
4078      return Error(Operands[5]->getStartLoc(),
4079                   "bitfield width must be in range [1,32-lsb]");
4080    return false;
4081  }
4082  case ARM::tLDMIA: {
4083    // If we're parsing Thumb2, the .w variant is available and handles
4084    // most cases that are normally illegal for a Thumb1 LDM
4085    // instruction. We'll make the transformation in processInstruction()
4086    // if necessary.
4087    //
4088    // Thumb LDM instructions are writeback iff the base register is not
4089    // in the register list.
4090    unsigned Rn = Inst.getOperand(0).getReg();
4091    bool hasWritebackToken =
4092      (static_cast<ARMOperand*>(Operands[3])->isToken() &&
4093       static_cast<ARMOperand*>(Operands[3])->getToken() == "!");
4094    bool listContainsBase;
4095    if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) && !isThumbTwo())
4096      return Error(Operands[3 + hasWritebackToken]->getStartLoc(),
4097                   "registers must be in range r0-r7");
4098    // If we should have writeback, then there should be a '!' token.
4099    if (!listContainsBase && !hasWritebackToken && !isThumbTwo())
4100      return Error(Operands[2]->getStartLoc(),
4101                   "writeback operator '!' expected");
4102    // If we should not have writeback, there must not be a '!'. This is
4103    // true even for the 32-bit wide encodings.
4104    if (listContainsBase && hasWritebackToken)
4105      return Error(Operands[3]->getStartLoc(),
4106                   "writeback operator '!' not allowed when base register "
4107                   "in register list");
4108
4109    break;
4110  }
4111  case ARM::t2LDMIA_UPD: {
4112    if (listContainsReg(Inst, 3, Inst.getOperand(0).getReg()))
4113      return Error(Operands[4]->getStartLoc(),
4114                   "writeback operator '!' not allowed when base register "
4115                   "in register list");
4116    break;
4117  }
4118  case ARM::tPOP: {
4119    bool listContainsBase;
4120    if (checkLowRegisterList(Inst, 3, 0, ARM::PC, listContainsBase))
4121      return Error(Operands[2]->getStartLoc(),
4122                   "registers must be in range r0-r7 or pc");
4123    break;
4124  }
4125  case ARM::tPUSH: {
4126    bool listContainsBase;
4127    if (checkLowRegisterList(Inst, 3, 0, ARM::LR, listContainsBase))
4128      return Error(Operands[2]->getStartLoc(),
4129                   "registers must be in range r0-r7 or lr");
4130    break;
4131  }
4132  case ARM::tSTMIA_UPD: {
4133    bool listContainsBase;
4134    if (checkLowRegisterList(Inst, 4, 0, 0, listContainsBase) && !isThumbTwo())
4135      return Error(Operands[4]->getStartLoc(),
4136                   "registers must be in range r0-r7");
4137    break;
4138  }
4139  }
4140
4141  return false;
4142}
4143
4144void ARMAsmParser::
4145processInstruction(MCInst &Inst,
4146                   const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
4147  switch (Inst.getOpcode()) {
4148  case ARM::LDMIA_UPD:
4149    // If this is a load of a single register via a 'pop', then we should use
4150    // a post-indexed LDR instruction instead, per the ARM ARM.
4151    if (static_cast<ARMOperand*>(Operands[0])->getToken() == "pop" &&
4152        Inst.getNumOperands() == 5) {
4153      MCInst TmpInst;
4154      TmpInst.setOpcode(ARM::LDR_POST_IMM);
4155      TmpInst.addOperand(Inst.getOperand(4)); // Rt
4156      TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
4157      TmpInst.addOperand(Inst.getOperand(1)); // Rn
4158      TmpInst.addOperand(MCOperand::CreateReg(0));  // am2offset
4159      TmpInst.addOperand(MCOperand::CreateImm(4));
4160      TmpInst.addOperand(Inst.getOperand(2)); // CondCode
4161      TmpInst.addOperand(Inst.getOperand(3));
4162      Inst = TmpInst;
4163    }
4164    break;
4165  case ARM::STMDB_UPD:
4166    // If this is a store of a single register via a 'push', then we should use
4167    // a pre-indexed STR instruction instead, per the ARM ARM.
4168    if (static_cast<ARMOperand*>(Operands[0])->getToken() == "push" &&
4169        Inst.getNumOperands() == 5) {
4170      MCInst TmpInst;
4171      TmpInst.setOpcode(ARM::STR_PRE_IMM);
4172      TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
4173      TmpInst.addOperand(Inst.getOperand(4)); // Rt
4174      TmpInst.addOperand(Inst.getOperand(1)); // addrmode_imm12
4175      TmpInst.addOperand(MCOperand::CreateImm(-4));
4176      TmpInst.addOperand(Inst.getOperand(2)); // CondCode
4177      TmpInst.addOperand(Inst.getOperand(3));
4178      Inst = TmpInst;
4179    }
4180    break;
4181  case ARM::tADDi8:
4182    // If the immediate is in the range 0-7, we want tADDi3 iff Rd was
4183    // explicitly specified. From the ARM ARM: "Encoding T1 is preferred
4184    // to encoding T2 if <Rd> is specified and encoding T2 is preferred
4185    // to encoding T1 if <Rd> is omitted."
4186    if (Inst.getOperand(3).getImm() < 8 && Operands.size() == 6)
4187      Inst.setOpcode(ARM::tADDi3);
4188    break;
4189  case ARM::tSUBi8:
4190    // If the immediate is in the range 0-7, we want tADDi3 iff Rd was
4191    // explicitly specified. From the ARM ARM: "Encoding T1 is preferred
4192    // to encoding T2 if <Rd> is specified and encoding T2 is preferred
4193    // to encoding T1 if <Rd> is omitted."
4194    if (Inst.getOperand(3).getImm() < 8 && Operands.size() == 6)
4195      Inst.setOpcode(ARM::tSUBi3);
4196    break;
4197  case ARM::tB:
4198    // A Thumb conditional branch outside of an IT block is a tBcc.
4199    if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock())
4200      Inst.setOpcode(ARM::tBcc);
4201    break;
4202  case ARM::t2B:
4203    // A Thumb2 conditional branch outside of an IT block is a t2Bcc.
4204    if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock())
4205      Inst.setOpcode(ARM::t2Bcc);
4206    break;
4207  case ARM::t2Bcc:
4208    // If the conditional is AL or we're in an IT block, we really want t2B.
4209    if (Inst.getOperand(1).getImm() == ARMCC::AL || inITBlock())
4210      Inst.setOpcode(ARM::t2B);
4211    break;
4212  case ARM::tBcc:
4213    // If the conditional is AL, we really want tB.
4214    if (Inst.getOperand(1).getImm() == ARMCC::AL)
4215      Inst.setOpcode(ARM::tB);
4216    break;
4217  case ARM::tLDMIA: {
4218    // If the register list contains any high registers, or if the writeback
4219    // doesn't match what tLDMIA can do, we need to use the 32-bit encoding
4220    // instead if we're in Thumb2. Otherwise, this should have generated
4221    // an error in validateInstruction().
4222    unsigned Rn = Inst.getOperand(0).getReg();
4223    bool hasWritebackToken =
4224      (static_cast<ARMOperand*>(Operands[3])->isToken() &&
4225       static_cast<ARMOperand*>(Operands[3])->getToken() == "!");
4226    bool listContainsBase;
4227    if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) ||
4228        (!listContainsBase && !hasWritebackToken) ||
4229        (listContainsBase && hasWritebackToken)) {
4230      // 16-bit encoding isn't sufficient. Switch to the 32-bit version.
4231      assert (isThumbTwo());
4232      Inst.setOpcode(hasWritebackToken ? ARM::t2LDMIA_UPD : ARM::t2LDMIA);
4233      // If we're switching to the updating version, we need to insert
4234      // the writeback tied operand.
4235      if (hasWritebackToken)
4236        Inst.insert(Inst.begin(),
4237                    MCOperand::CreateReg(Inst.getOperand(0).getReg()));
4238    }
4239    break;
4240  }
4241  case ARM::tSTMIA_UPD: {
4242    // If the register list contains any high registers, we need to use
4243    // the 32-bit encoding instead if we're in Thumb2. Otherwise, this
4244    // should have generated an error in validateInstruction().
4245    unsigned Rn = Inst.getOperand(0).getReg();
4246    bool listContainsBase;
4247    if (checkLowRegisterList(Inst, 4, Rn, 0, listContainsBase)) {
4248      // 16-bit encoding isn't sufficient. Switch to the 32-bit version.
4249      assert (isThumbTwo());
4250      Inst.setOpcode(ARM::t2STMIA_UPD);
4251    }
4252    break;
4253  }
4254  case ARM::t2MOVi: {
4255    // If we can use the 16-bit encoding and the user didn't explicitly
4256    // request the 32-bit variant, transform it here.
4257    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
4258        Inst.getOperand(1).getImm() <= 255 &&
4259        ((!inITBlock() && Inst.getOperand(2).getImm() == ARMCC::AL &&
4260         Inst.getOperand(4).getReg() == ARM::CPSR) ||
4261        (inITBlock() && Inst.getOperand(4).getReg() == 0)) &&
4262        (!static_cast<ARMOperand*>(Operands[2])->isToken() ||
4263         static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) {
4264      // The operands aren't in the same order for tMOVi8...
4265      MCInst TmpInst;
4266      TmpInst.setOpcode(ARM::tMOVi8);
4267      TmpInst.addOperand(Inst.getOperand(0));
4268      TmpInst.addOperand(Inst.getOperand(4));
4269      TmpInst.addOperand(Inst.getOperand(1));
4270      TmpInst.addOperand(Inst.getOperand(2));
4271      TmpInst.addOperand(Inst.getOperand(3));
4272      Inst = TmpInst;
4273    }
4274    break;
4275  }
4276  case ARM::t2MOVr: {
4277    // If we can use the 16-bit encoding and the user didn't explicitly
4278    // request the 32-bit variant, transform it here.
4279    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
4280        isARMLowRegister(Inst.getOperand(1).getReg()) &&
4281        Inst.getOperand(2).getImm() == ARMCC::AL &&
4282        Inst.getOperand(4).getReg() == ARM::CPSR &&
4283        (!static_cast<ARMOperand*>(Operands[2])->isToken() ||
4284         static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) {
4285      // The operands aren't the same for tMOV[S]r... (no cc_out)
4286      MCInst TmpInst;
4287      TmpInst.setOpcode(Inst.getOperand(4).getReg() ? ARM::tMOVSr : ARM::tMOVr);
4288      TmpInst.addOperand(Inst.getOperand(0));
4289      TmpInst.addOperand(Inst.getOperand(1));
4290      TmpInst.addOperand(Inst.getOperand(2));
4291      TmpInst.addOperand(Inst.getOperand(3));
4292      Inst = TmpInst;
4293    }
4294    break;
4295  }
4296  case ARM::t2SXTH:
4297  case ARM::t2SXTB:
4298  case ARM::t2UXTH:
4299  case ARM::t2UXTB: {
4300    // If we can use the 16-bit encoding and the user didn't explicitly
4301    // request the 32-bit variant, transform it here.
4302    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
4303        isARMLowRegister(Inst.getOperand(1).getReg()) &&
4304        Inst.getOperand(2).getImm() == 0 &&
4305        (!static_cast<ARMOperand*>(Operands[2])->isToken() ||
4306         static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) {
4307      unsigned NewOpc;
4308      switch (Inst.getOpcode()) {
4309      default: llvm_unreachable("Illegal opcode!");
4310      case ARM::t2SXTH: NewOpc = ARM::tSXTH; break;
4311      case ARM::t2SXTB: NewOpc = ARM::tSXTB; break;
4312      case ARM::t2UXTH: NewOpc = ARM::tUXTH; break;
4313      case ARM::t2UXTB: NewOpc = ARM::tUXTB; break;
4314      }
4315      // The operands aren't the same for thumb1 (no rotate operand).
4316      MCInst TmpInst;
4317      TmpInst.setOpcode(NewOpc);
4318      TmpInst.addOperand(Inst.getOperand(0));
4319      TmpInst.addOperand(Inst.getOperand(1));
4320      TmpInst.addOperand(Inst.getOperand(3));
4321      TmpInst.addOperand(Inst.getOperand(4));
4322      Inst = TmpInst;
4323    }
4324    break;
4325  }
4326  case ARM::t2IT: {
4327    // The mask bits for all but the first condition are represented as
4328    // the low bit of the condition code value implies 't'. We currently
4329    // always have 1 implies 't', so XOR toggle the bits if the low bit
4330    // of the condition code is zero. The encoding also expects the low
4331    // bit of the condition to be encoded as bit 4 of the mask operand,
4332    // so mask that in if needed
4333    MCOperand &MO = Inst.getOperand(1);
4334    unsigned Mask = MO.getImm();
4335    unsigned OrigMask = Mask;
4336    unsigned TZ = CountTrailingZeros_32(Mask);
4337    if ((Inst.getOperand(0).getImm() & 1) == 0) {
4338      assert(Mask && TZ <= 3 && "illegal IT mask value!");
4339      for (unsigned i = 3; i != TZ; --i)
4340        Mask ^= 1 << i;
4341    } else
4342      Mask |= 0x10;
4343    MO.setImm(Mask);
4344
4345    // Set up the IT block state according to the IT instruction we just
4346    // matched.
4347    assert(!inITBlock() && "nested IT blocks?!");
4348    ITState.Cond = ARMCC::CondCodes(Inst.getOperand(0).getImm());
4349    ITState.Mask = OrigMask; // Use the original mask, not the updated one.
4350    ITState.CurPosition = 0;
4351    ITState.FirstCond = true;
4352    break;
4353  }
4354  }
4355}
4356
4357unsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
4358  // 16-bit thumb arithmetic instructions either require or preclude the 'S'
4359  // suffix depending on whether they're in an IT block or not.
4360  unsigned Opc = Inst.getOpcode();
4361  MCInstrDesc &MCID = getInstDesc(Opc);
4362  if (MCID.TSFlags & ARMII::ThumbArithFlagSetting) {
4363    assert(MCID.hasOptionalDef() &&
4364           "optionally flag setting instruction missing optional def operand");
4365    assert(MCID.NumOperands == Inst.getNumOperands() &&
4366           "operand count mismatch!");
4367    // Find the optional-def operand (cc_out).
4368    unsigned OpNo;
4369    for (OpNo = 0;
4370         !MCID.OpInfo[OpNo].isOptionalDef() && OpNo < MCID.NumOperands;
4371         ++OpNo)
4372      ;
4373    // If we're parsing Thumb1, reject it completely.
4374    if (isThumbOne() && Inst.getOperand(OpNo).getReg() != ARM::CPSR)
4375      return Match_MnemonicFail;
4376    // If we're parsing Thumb2, which form is legal depends on whether we're
4377    // in an IT block.
4378    if (isThumbTwo() && Inst.getOperand(OpNo).getReg() != ARM::CPSR &&
4379        !inITBlock())
4380      return Match_RequiresITBlock;
4381    if (isThumbTwo() && Inst.getOperand(OpNo).getReg() == ARM::CPSR &&
4382        inITBlock())
4383      return Match_RequiresNotITBlock;
4384  }
4385  // Some high-register supporting Thumb1 encodings only allow both registers
4386  // to be from r0-r7 when in Thumb2.
4387  else if (Opc == ARM::tADDhirr && isThumbOne() &&
4388           isARMLowRegister(Inst.getOperand(1).getReg()) &&
4389           isARMLowRegister(Inst.getOperand(2).getReg()))
4390    return Match_RequiresThumb2;
4391  // Others only require ARMv6 or later.
4392  else if (Opc == ARM::tMOVr && isThumbOne() && !hasV6Ops() &&
4393           isARMLowRegister(Inst.getOperand(0).getReg()) &&
4394           isARMLowRegister(Inst.getOperand(1).getReg()))
4395    return Match_RequiresV6;
4396  return Match_Success;
4397}
4398
4399bool ARMAsmParser::
4400MatchAndEmitInstruction(SMLoc IDLoc,
4401                        SmallVectorImpl<MCParsedAsmOperand*> &Operands,
4402                        MCStreamer &Out) {
4403  MCInst Inst;
4404  unsigned ErrorInfo;
4405  unsigned MatchResult;
4406  MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo);
4407  switch (MatchResult) {
4408  default: break;
4409  case Match_Success:
4410    // Context sensitive operand constraints aren't handled by the matcher,
4411    // so check them here.
4412    if (validateInstruction(Inst, Operands)) {
4413      // Still progress the IT block, otherwise one wrong condition causes
4414      // nasty cascading errors.
4415      forwardITPosition();
4416      return true;
4417    }
4418
4419    // Some instructions need post-processing to, for example, tweak which
4420    // encoding is selected.
4421    processInstruction(Inst, Operands);
4422
4423    // Only move forward at the very end so that everything in validate
4424    // and process gets a consistent answer about whether we're in an IT
4425    // block.
4426    forwardITPosition();
4427
4428    Out.EmitInstruction(Inst);
4429    return false;
4430  case Match_MissingFeature:
4431    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
4432    return true;
4433  case Match_InvalidOperand: {
4434    SMLoc ErrorLoc = IDLoc;
4435    if (ErrorInfo != ~0U) {
4436      if (ErrorInfo >= Operands.size())
4437        return Error(IDLoc, "too few operands for instruction");
4438
4439      ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc();
4440      if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
4441    }
4442
4443    return Error(ErrorLoc, "invalid operand for instruction");
4444  }
4445  case Match_MnemonicFail:
4446    return Error(IDLoc, "invalid instruction");
4447  case Match_ConversionFail:
4448    // The converter function will have already emited a diagnostic.
4449    return true;
4450  case Match_RequiresNotITBlock:
4451    return Error(IDLoc, "flag setting instruction only valid outside IT block");
4452  case Match_RequiresITBlock:
4453    return Error(IDLoc, "instruction only valid inside IT block");
4454  case Match_RequiresV6:
4455    return Error(IDLoc, "instruction variant requires ARMv6 or later");
4456  case Match_RequiresThumb2:
4457    return Error(IDLoc, "instruction variant requires Thumb2");
4458  }
4459
4460  llvm_unreachable("Implement any new match types added!");
4461  return true;
4462}
4463
4464/// parseDirective parses the arm specific directives
4465bool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
4466  StringRef IDVal = DirectiveID.getIdentifier();
4467  if (IDVal == ".word")
4468    return parseDirectiveWord(4, DirectiveID.getLoc());
4469  else if (IDVal == ".thumb")
4470    return parseDirectiveThumb(DirectiveID.getLoc());
4471  else if (IDVal == ".thumb_func")
4472    return parseDirectiveThumbFunc(DirectiveID.getLoc());
4473  else if (IDVal == ".code")
4474    return parseDirectiveCode(DirectiveID.getLoc());
4475  else if (IDVal == ".syntax")
4476    return parseDirectiveSyntax(DirectiveID.getLoc());
4477  return true;
4478}
4479
4480/// parseDirectiveWord
4481///  ::= .word [ expression (, expression)* ]
4482bool ARMAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
4483  if (getLexer().isNot(AsmToken::EndOfStatement)) {
4484    for (;;) {
4485      const MCExpr *Value;
4486      if (getParser().ParseExpression(Value))
4487        return true;
4488
4489      getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/);
4490
4491      if (getLexer().is(AsmToken::EndOfStatement))
4492        break;
4493
4494      // FIXME: Improve diagnostic.
4495      if (getLexer().isNot(AsmToken::Comma))
4496        return Error(L, "unexpected token in directive");
4497      Parser.Lex();
4498    }
4499  }
4500
4501  Parser.Lex();
4502  return false;
4503}
4504
4505/// parseDirectiveThumb
4506///  ::= .thumb
4507bool ARMAsmParser::parseDirectiveThumb(SMLoc L) {
4508  if (getLexer().isNot(AsmToken::EndOfStatement))
4509    return Error(L, "unexpected token in directive");
4510  Parser.Lex();
4511
4512  // TODO: set thumb mode
4513  // TODO: tell the MC streamer the mode
4514  // getParser().getStreamer().Emit???();
4515  return false;
4516}
4517
4518/// parseDirectiveThumbFunc
4519///  ::= .thumbfunc symbol_name
4520bool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) {
4521  const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo();
4522  bool isMachO = MAI.hasSubsectionsViaSymbols();
4523  StringRef Name;
4524
4525  // Darwin asm has function name after .thumb_func direction
4526  // ELF doesn't
4527  if (isMachO) {
4528    const AsmToken &Tok = Parser.getTok();
4529    if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String))
4530      return Error(L, "unexpected token in .thumb_func directive");
4531    Name = Tok.getString();
4532    Parser.Lex(); // Consume the identifier token.
4533  }
4534
4535  if (getLexer().isNot(AsmToken::EndOfStatement))
4536    return Error(L, "unexpected token in directive");
4537  Parser.Lex();
4538
4539  // FIXME: assuming function name will be the line following .thumb_func
4540  if (!isMachO) {
4541    Name = Parser.getTok().getString();
4542  }
4543
4544  // Mark symbol as a thumb symbol.
4545  MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name);
4546  getParser().getStreamer().EmitThumbFunc(Func);
4547  return false;
4548}
4549
4550/// parseDirectiveSyntax
4551///  ::= .syntax unified | divided
4552bool ARMAsmParser::parseDirectiveSyntax(SMLoc L) {
4553  const AsmToken &Tok = Parser.getTok();
4554  if (Tok.isNot(AsmToken::Identifier))
4555    return Error(L, "unexpected token in .syntax directive");
4556  StringRef Mode = Tok.getString();
4557  if (Mode == "unified" || Mode == "UNIFIED")
4558    Parser.Lex();
4559  else if (Mode == "divided" || Mode == "DIVIDED")
4560    return Error(L, "'.syntax divided' arm asssembly not supported");
4561  else
4562    return Error(L, "unrecognized syntax mode in .syntax directive");
4563
4564  if (getLexer().isNot(AsmToken::EndOfStatement))
4565    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
4566  Parser.Lex();
4567
4568  // TODO tell the MC streamer the mode
4569  // getParser().getStreamer().Emit???();
4570  return false;
4571}
4572
4573/// parseDirectiveCode
4574///  ::= .code 16 | 32
4575bool ARMAsmParser::parseDirectiveCode(SMLoc L) {
4576  const AsmToken &Tok = Parser.getTok();
4577  if (Tok.isNot(AsmToken::Integer))
4578    return Error(L, "unexpected token in .code directive");
4579  int64_t Val = Parser.getTok().getIntVal();
4580  if (Val == 16)
4581    Parser.Lex();
4582  else if (Val == 32)
4583    Parser.Lex();
4584  else
4585    return Error(L, "invalid operand to .code directive");
4586
4587  if (getLexer().isNot(AsmToken::EndOfStatement))
4588    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
4589  Parser.Lex();
4590
4591  if (Val == 16) {
4592    if (!isThumb())
4593      SwitchMode();
4594    getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
4595  } else {
4596    if (isThumb())
4597      SwitchMode();
4598    getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
4599  }
4600
4601  return false;
4602}
4603
4604extern "C" void LLVMInitializeARMAsmLexer();
4605
4606/// Force static initialization.
4607extern "C" void LLVMInitializeARMAsmParser() {
4608  RegisterMCAsmParser<ARMAsmParser> X(TheARMTarget);
4609  RegisterMCAsmParser<ARMAsmParser> Y(TheThumbTarget);
4610  LLVMInitializeARMAsmLexer();
4611}
4612
4613#define GET_REGISTER_MATCHER
4614#define GET_MATCHER_IMPLEMENTATION
4615#include "ARMGenAsmMatcher.inc"
4616