ARMAsmParser.cpp revision eac0796542d098caa371856d545faa6cdab5aad3
1//===-- ARMAsmParser.cpp - Parse ARM assembly to MCInst instructions ------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "ARM.h"
11#include "ARMAddressingModes.h"
12#include "ARMMCExpr.h"
13#include "ARMBaseRegisterInfo.h"
14#include "ARMSubtarget.h"
15#include "llvm/MC/MCParser/MCAsmLexer.h"
16#include "llvm/MC/MCParser/MCAsmParser.h"
17#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
18#include "llvm/MC/MCAsmInfo.h"
19#include "llvm/MC/MCContext.h"
20#include "llvm/MC/MCStreamer.h"
21#include "llvm/MC/MCExpr.h"
22#include "llvm/MC/MCInst.h"
23#include "llvm/MC/MCSubtargetInfo.h"
24#include "llvm/Target/TargetRegistry.h"
25#include "llvm/Target/TargetAsmParser.h"
26#include "llvm/Support/SourceMgr.h"
27#include "llvm/Support/raw_ostream.h"
28#include "llvm/ADT/OwningPtr.h"
29#include "llvm/ADT/SmallVector.h"
30#include "llvm/ADT/StringExtras.h"
31#include "llvm/ADT/StringSwitch.h"
32#include "llvm/ADT/Twine.h"
33
34#define GET_SUBTARGETINFO_ENUM
35#include "ARMGenSubtargetInfo.inc"
36
37using namespace llvm;
38
39namespace {
40
41class ARMOperand;
42
43class ARMAsmParser : public TargetAsmParser {
44  MCSubtargetInfo &STI;
45  MCAsmParser &Parser;
46
47  MCAsmParser &getParser() const { return Parser; }
48  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
49
50  void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }
51  bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
52
53  int TryParseRegister();
54  virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
55  bool TryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &);
56  int TryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &);
57  bool ParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &);
58  bool ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &,
59                   ARMII::AddrMode AddrMode);
60  bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic);
61  bool ParsePrefix(ARMMCExpr::VariantKind &RefKind);
62  const MCExpr *ApplyPrefixToExpr(const MCExpr *E,
63                                  MCSymbolRefExpr::VariantKind Variant);
64
65
66  bool ParseMemoryOffsetReg(bool &Negative,
67                            bool &OffsetRegShifted,
68                            enum ARM_AM::ShiftOpc &ShiftType,
69                            const MCExpr *&ShiftAmount,
70                            const MCExpr *&Offset,
71                            bool &OffsetIsReg,
72                            int &OffsetRegNum,
73                            SMLoc &E);
74  bool ParseShift(enum ARM_AM::ShiftOpc &St,
75                  const MCExpr *&ShiftAmount, SMLoc &E);
76  bool ParseDirectiveWord(unsigned Size, SMLoc L);
77  bool ParseDirectiveThumb(SMLoc L);
78  bool ParseDirectiveThumbFunc(SMLoc L);
79  bool ParseDirectiveCode(SMLoc L);
80  bool ParseDirectiveSyntax(SMLoc L);
81
82  bool MatchAndEmitInstruction(SMLoc IDLoc,
83                               SmallVectorImpl<MCParsedAsmOperand*> &Operands,
84                               MCStreamer &Out);
85  void GetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
86                             bool &CanAcceptPredicationCode);
87
88  bool isThumb() const {
89    // FIXME: Can tablegen auto-generate this?
90    return (STI.getFeatureBits() & ARM::ModeThumb) != 0;
91  }
92  bool isThumbOne() const {
93    return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) == 0;
94  }
95  void SwitchMode() {
96    unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb));
97    setAvailableFeatures(FB);
98  }
99
100  /// @name Auto-generated Match Functions
101  /// {
102
103#define GET_ASSEMBLER_HEADER
104#include "ARMGenAsmMatcher.inc"
105
106  /// }
107
108  OperandMatchResultTy tryParseCoprocNumOperand(
109    SmallVectorImpl<MCParsedAsmOperand*>&);
110  OperandMatchResultTy tryParseCoprocRegOperand(
111    SmallVectorImpl<MCParsedAsmOperand*>&);
112  OperandMatchResultTy tryParseMemBarrierOptOperand(
113    SmallVectorImpl<MCParsedAsmOperand*>&);
114  OperandMatchResultTy tryParseProcIFlagsOperand(
115    SmallVectorImpl<MCParsedAsmOperand*>&);
116  OperandMatchResultTy tryParseMSRMaskOperand(
117    SmallVectorImpl<MCParsedAsmOperand*>&);
118  OperandMatchResultTy tryParseMemMode2Operand(
119    SmallVectorImpl<MCParsedAsmOperand*>&);
120  OperandMatchResultTy tryParseMemMode3Operand(
121    SmallVectorImpl<MCParsedAsmOperand*>&);
122
123  // Asm Match Converter Methods
124  bool CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
125                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
126  bool CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
127                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
128  bool CvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
129                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
130  bool CvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
131                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
132
133public:
134  ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser)
135    : TargetAsmParser(), STI(_STI), Parser(_Parser) {
136    MCAsmParserExtension::Initialize(_Parser);
137
138    // Initialize the set of available features.
139    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
140  }
141
142  virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc,
143                                SmallVectorImpl<MCParsedAsmOperand*> &Operands);
144  virtual bool ParseDirective(AsmToken DirectiveID);
145};
146} // end anonymous namespace
147
148namespace {
149
150/// ARMOperand - Instances of this class represent a parsed ARM machine
151/// instruction.
152class ARMOperand : public MCParsedAsmOperand {
153  enum KindTy {
154    CondCode,
155    CCOut,
156    CoprocNum,
157    CoprocReg,
158    Immediate,
159    MemBarrierOpt,
160    Memory,
161    MSRMask,
162    ProcIFlags,
163    Register,
164    RegisterList,
165    DPRRegisterList,
166    SPRRegisterList,
167    ShiftedRegister,
168    Shifter,
169    Token
170  } Kind;
171
172  SMLoc StartLoc, EndLoc;
173  SmallVector<unsigned, 8> Registers;
174
175  union {
176    struct {
177      ARMCC::CondCodes Val;
178    } CC;
179
180    struct {
181      ARM_MB::MemBOpt Val;
182    } MBOpt;
183
184    struct {
185      unsigned Val;
186    } Cop;
187
188    struct {
189      ARM_PROC::IFlags Val;
190    } IFlags;
191
192    struct {
193      unsigned Val;
194    } MMask;
195
196    struct {
197      const char *Data;
198      unsigned Length;
199    } Tok;
200
201    struct {
202      unsigned RegNum;
203    } Reg;
204
205    struct {
206      const MCExpr *Val;
207    } Imm;
208
209    /// Combined record for all forms of ARM address expressions.
210    struct {
211      ARMII::AddrMode AddrMode;
212      unsigned BaseRegNum;
213      union {
214        unsigned RegNum;     ///< Offset register num, when OffsetIsReg.
215        const MCExpr *Value; ///< Offset value, when !OffsetIsReg.
216      } Offset;
217      const MCExpr *ShiftAmount;     // used when OffsetRegShifted is true
218      enum ARM_AM::ShiftOpc ShiftType; // used when OffsetRegShifted is true
219      unsigned OffsetRegShifted : 1; // only used when OffsetIsReg is true
220      unsigned Preindexed       : 1;
221      unsigned Postindexed      : 1;
222      unsigned OffsetIsReg      : 1;
223      unsigned Negative         : 1; // only used when OffsetIsReg is true
224      unsigned Writeback        : 1;
225    } Mem;
226
227    struct {
228      ARM_AM::ShiftOpc ShiftTy;
229      unsigned Imm;
230    } Shift;
231    struct {
232      ARM_AM::ShiftOpc ShiftTy;
233      unsigned SrcReg;
234      unsigned ShiftReg;
235      unsigned ShiftImm;
236    } ShiftedReg;
237  };
238
239  ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
240public:
241  ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() {
242    Kind = o.Kind;
243    StartLoc = o.StartLoc;
244    EndLoc = o.EndLoc;
245    switch (Kind) {
246    case CondCode:
247      CC = o.CC;
248      break;
249    case Token:
250      Tok = o.Tok;
251      break;
252    case CCOut:
253    case Register:
254      Reg = o.Reg;
255      break;
256    case RegisterList:
257    case DPRRegisterList:
258    case SPRRegisterList:
259      Registers = o.Registers;
260      break;
261    case CoprocNum:
262    case CoprocReg:
263      Cop = o.Cop;
264      break;
265    case Immediate:
266      Imm = o.Imm;
267      break;
268    case MemBarrierOpt:
269      MBOpt = o.MBOpt;
270      break;
271    case Memory:
272      Mem = o.Mem;
273      break;
274    case MSRMask:
275      MMask = o.MMask;
276      break;
277    case ProcIFlags:
278      IFlags = o.IFlags;
279      break;
280    case Shifter:
281      Shift = o.Shift;
282      break;
283    case ShiftedRegister:
284      ShiftedReg = o.ShiftedReg;
285      break;
286    }
287  }
288
289  /// getStartLoc - Get the location of the first token of this operand.
290  SMLoc getStartLoc() const { return StartLoc; }
291  /// getEndLoc - Get the location of the last token of this operand.
292  SMLoc getEndLoc() const { return EndLoc; }
293
294  ARMCC::CondCodes getCondCode() const {
295    assert(Kind == CondCode && "Invalid access!");
296    return CC.Val;
297  }
298
299  unsigned getCoproc() const {
300    assert((Kind == CoprocNum || Kind == CoprocReg) && "Invalid access!");
301    return Cop.Val;
302  }
303
304  StringRef getToken() const {
305    assert(Kind == Token && "Invalid access!");
306    return StringRef(Tok.Data, Tok.Length);
307  }
308
309  unsigned getReg() const {
310    assert((Kind == Register || Kind == CCOut) && "Invalid access!");
311    return Reg.RegNum;
312  }
313
314  const SmallVectorImpl<unsigned> &getRegList() const {
315    assert((Kind == RegisterList || Kind == DPRRegisterList ||
316            Kind == SPRRegisterList) && "Invalid access!");
317    return Registers;
318  }
319
320  const MCExpr *getImm() const {
321    assert(Kind == Immediate && "Invalid access!");
322    return Imm.Val;
323  }
324
325  ARM_MB::MemBOpt getMemBarrierOpt() const {
326    assert(Kind == MemBarrierOpt && "Invalid access!");
327    return MBOpt.Val;
328  }
329
330  ARM_PROC::IFlags getProcIFlags() const {
331    assert(Kind == ProcIFlags && "Invalid access!");
332    return IFlags.Val;
333  }
334
335  unsigned getMSRMask() const {
336    assert(Kind == MSRMask && "Invalid access!");
337    return MMask.Val;
338  }
339
340  /// @name Memory Operand Accessors
341  /// @{
342  ARMII::AddrMode getMemAddrMode() const {
343    return Mem.AddrMode;
344  }
345  unsigned getMemBaseRegNum() const {
346    return Mem.BaseRegNum;
347  }
348  unsigned getMemOffsetRegNum() const {
349    assert(Mem.OffsetIsReg && "Invalid access!");
350    return Mem.Offset.RegNum;
351  }
352  const MCExpr *getMemOffset() const {
353    assert(!Mem.OffsetIsReg && "Invalid access!");
354    return Mem.Offset.Value;
355  }
356  unsigned getMemOffsetRegShifted() const {
357    assert(Mem.OffsetIsReg && "Invalid access!");
358    return Mem.OffsetRegShifted;
359  }
360  const MCExpr *getMemShiftAmount() const {
361    assert(Mem.OffsetIsReg && Mem.OffsetRegShifted && "Invalid access!");
362    return Mem.ShiftAmount;
363  }
364  enum ARM_AM::ShiftOpc getMemShiftType() const {
365    assert(Mem.OffsetIsReg && Mem.OffsetRegShifted && "Invalid access!");
366    return Mem.ShiftType;
367  }
368  bool getMemPreindexed() const { return Mem.Preindexed; }
369  bool getMemPostindexed() const { return Mem.Postindexed; }
370  bool getMemOffsetIsReg() const { return Mem.OffsetIsReg; }
371  bool getMemNegative() const { return Mem.Negative; }
372  bool getMemWriteback() const { return Mem.Writeback; }
373
374  /// @}
375
376  bool isCoprocNum() const { return Kind == CoprocNum; }
377  bool isCoprocReg() const { return Kind == CoprocReg; }
378  bool isCondCode() const { return Kind == CondCode; }
379  bool isCCOut() const { return Kind == CCOut; }
380  bool isImm() const { return Kind == Immediate; }
381  bool isImm0_255() const {
382    if (Kind != Immediate)
383      return false;
384    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
385    if (!CE) return false;
386    int64_t Value = CE->getValue();
387    return Value >= 0 && Value < 256;
388  }
389  bool isImm0_7() const {
390    if (Kind != Immediate)
391      return false;
392    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
393    if (!CE) return false;
394    int64_t Value = CE->getValue();
395    return Value >= 0 && Value < 8;
396  }
397  bool isImm0_15() const {
398    if (Kind != Immediate)
399      return false;
400    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
401    if (!CE) return false;
402    int64_t Value = CE->getValue();
403    return Value >= 0 && Value < 16;
404  }
405  bool isImm0_65535() const {
406    if (Kind != Immediate)
407      return false;
408    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
409    if (!CE) return false;
410    int64_t Value = CE->getValue();
411    return Value >= 0 && Value < 65536;
412  }
413  bool isT2SOImm() const {
414    if (Kind != Immediate)
415      return false;
416    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
417    if (!CE) return false;
418    int64_t Value = CE->getValue();
419    return ARM_AM::getT2SOImmVal(Value) != -1;
420  }
421  bool isReg() const { return Kind == Register; }
422  bool isRegList() const { return Kind == RegisterList; }
423  bool isDPRRegList() const { return Kind == DPRRegisterList; }
424  bool isSPRRegList() const { return Kind == SPRRegisterList; }
425  bool isToken() const { return Kind == Token; }
426  bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; }
427  bool isMemory() const { return Kind == Memory; }
428  bool isShifter() const { return Kind == Shifter; }
429  bool isShiftedReg() const { return Kind == ShiftedRegister; }
430  bool isMemMode2() const {
431    if (getMemAddrMode() != ARMII::AddrMode2)
432      return false;
433
434    if (getMemOffsetIsReg())
435      return true;
436
437    if (getMemNegative() &&
438        !(getMemPostindexed() || getMemPreindexed()))
439      return false;
440
441    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
442    if (!CE) return false;
443    int64_t Value = CE->getValue();
444
445    // The offset must be in the range 0-4095 (imm12).
446    if (Value > 4095 || Value < -4095)
447      return false;
448
449    return true;
450  }
451  bool isMemMode3() const {
452    if (getMemAddrMode() != ARMII::AddrMode3)
453      return false;
454
455    if (getMemOffsetIsReg()) {
456      if (getMemOffsetRegShifted())
457        return false; // No shift with offset reg allowed
458      return true;
459    }
460
461    if (getMemNegative() &&
462        !(getMemPostindexed() || getMemPreindexed()))
463      return false;
464
465    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
466    if (!CE) return false;
467    int64_t Value = CE->getValue();
468
469    // The offset must be in the range 0-255 (imm8).
470    if (Value > 255 || Value < -255)
471      return false;
472
473    return true;
474  }
475  bool isMemMode5() const {
476    if (!isMemory() || getMemOffsetIsReg() || getMemWriteback() ||
477        getMemNegative())
478      return false;
479
480    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
481    if (!CE) return false;
482
483    // The offset must be a multiple of 4 in the range 0-1020.
484    int64_t Value = CE->getValue();
485    return ((Value & 0x3) == 0 && Value <= 1020 && Value >= -1020);
486  }
487  bool isMemMode7() const {
488    if (!isMemory() ||
489        getMemPreindexed() ||
490        getMemPostindexed() ||
491        getMemOffsetIsReg() ||
492        getMemNegative() ||
493        getMemWriteback())
494      return false;
495
496    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
497    if (!CE) return false;
498
499    if (CE->getValue())
500      return false;
501
502    return true;
503  }
504  bool isMemModeRegThumb() const {
505    if (!isMemory() || !getMemOffsetIsReg() || getMemWriteback())
506      return false;
507    return true;
508  }
509  bool isMemModeImmThumb() const {
510    if (!isMemory() || getMemOffsetIsReg() || getMemWriteback())
511      return false;
512
513    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
514    if (!CE) return false;
515
516    // The offset must be a multiple of 4 in the range 0-124.
517    uint64_t Value = CE->getValue();
518    return ((Value & 0x3) == 0 && Value <= 124);
519  }
520  bool isMSRMask() const { return Kind == MSRMask; }
521  bool isProcIFlags() const { return Kind == ProcIFlags; }
522
523  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
524    // Add as immediates when possible.  Null MCExpr = 0.
525    if (Expr == 0)
526      Inst.addOperand(MCOperand::CreateImm(0));
527    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
528      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
529    else
530      Inst.addOperand(MCOperand::CreateExpr(Expr));
531  }
532
533  void addCondCodeOperands(MCInst &Inst, unsigned N) const {
534    assert(N == 2 && "Invalid number of operands!");
535    Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode())));
536    unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR;
537    Inst.addOperand(MCOperand::CreateReg(RegNum));
538  }
539
540  void addCoprocNumOperands(MCInst &Inst, unsigned N) const {
541    assert(N == 1 && "Invalid number of operands!");
542    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
543  }
544
545  void addCoprocRegOperands(MCInst &Inst, unsigned N) const {
546    assert(N == 1 && "Invalid number of operands!");
547    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
548  }
549
550  void addCCOutOperands(MCInst &Inst, unsigned N) const {
551    assert(N == 1 && "Invalid number of operands!");
552    Inst.addOperand(MCOperand::CreateReg(getReg()));
553  }
554
555  void addRegOperands(MCInst &Inst, unsigned N) const {
556    assert(N == 1 && "Invalid number of operands!");
557    Inst.addOperand(MCOperand::CreateReg(getReg()));
558  }
559
560  void addShiftedRegOperands(MCInst &Inst, unsigned N) const {
561    assert(N == 3 && "Invalid number of operands!");
562    assert(isShiftedReg() && "addShiftedRegOperands() on non ShiftedReg!");
563    assert((ShiftedReg.ShiftReg == 0 ||
564            ARM_AM::getSORegOffset(ShiftedReg.ShiftImm) == 0) &&
565           "Invalid shifted register operand!");
566    Inst.addOperand(MCOperand::CreateReg(ShiftedReg.SrcReg));
567    Inst.addOperand(MCOperand::CreateReg(ShiftedReg.ShiftReg));
568    Inst.addOperand(MCOperand::CreateImm(
569      ARM_AM::getSORegOpc(ShiftedReg.ShiftTy, ShiftedReg.ShiftImm)));
570  }
571
572  void addShifterOperands(MCInst &Inst, unsigned N) const {
573    assert(N == 1 && "Invalid number of operands!");
574    Inst.addOperand(MCOperand::CreateImm(
575      ARM_AM::getSORegOpc(Shift.ShiftTy, 0)));
576  }
577
578  void addRegListOperands(MCInst &Inst, unsigned N) const {
579    assert(N == 1 && "Invalid number of operands!");
580    const SmallVectorImpl<unsigned> &RegList = getRegList();
581    for (SmallVectorImpl<unsigned>::const_iterator
582           I = RegList.begin(), E = RegList.end(); I != E; ++I)
583      Inst.addOperand(MCOperand::CreateReg(*I));
584  }
585
586  void addDPRRegListOperands(MCInst &Inst, unsigned N) const {
587    addRegListOperands(Inst, N);
588  }
589
590  void addSPRRegListOperands(MCInst &Inst, unsigned N) const {
591    addRegListOperands(Inst, N);
592  }
593
594  void addImmOperands(MCInst &Inst, unsigned N) const {
595    assert(N == 1 && "Invalid number of operands!");
596    addExpr(Inst, getImm());
597  }
598
599  void addImm0_255Operands(MCInst &Inst, unsigned N) const {
600    assert(N == 1 && "Invalid number of operands!");
601    addExpr(Inst, getImm());
602  }
603
604  void addImm0_7Operands(MCInst &Inst, unsigned N) const {
605    assert(N == 1 && "Invalid number of operands!");
606    addExpr(Inst, getImm());
607  }
608
609  void addImm0_15Operands(MCInst &Inst, unsigned N) const {
610    assert(N == 1 && "Invalid number of operands!");
611    addExpr(Inst, getImm());
612  }
613
614  void addImm0_65535Operands(MCInst &Inst, unsigned N) const {
615    assert(N == 1 && "Invalid number of operands!");
616    addExpr(Inst, getImm());
617  }
618
619  void addT2SOImmOperands(MCInst &Inst, unsigned N) const {
620    assert(N == 1 && "Invalid number of operands!");
621    addExpr(Inst, getImm());
622  }
623
624  void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const {
625    assert(N == 1 && "Invalid number of operands!");
626    Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt())));
627  }
628
629  void addMemMode7Operands(MCInst &Inst, unsigned N) const {
630    assert(N == 1 && isMemMode7() && "Invalid number of operands!");
631    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
632
633    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
634    (void)CE;
635    assert((CE || CE->getValue() == 0) &&
636           "No offset operand support in mode 7");
637  }
638
639  void addMemMode2Operands(MCInst &Inst, unsigned N) const {
640    assert(isMemMode2() && "Invalid mode or number of operands!");
641    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
642    unsigned IdxMode = (getMemPreindexed() | getMemPostindexed() << 1);
643
644    if (getMemOffsetIsReg()) {
645      Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum()));
646
647      ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : ARM_AM::add;
648      ARM_AM::ShiftOpc ShOpc = ARM_AM::no_shift;
649      int64_t ShiftAmount = 0;
650
651      if (getMemOffsetRegShifted()) {
652        ShOpc = getMemShiftType();
653        const MCConstantExpr *CE =
654                   dyn_cast<MCConstantExpr>(getMemShiftAmount());
655        ShiftAmount = CE->getValue();
656      }
657
658      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(AMOpc, ShiftAmount,
659                                           ShOpc, IdxMode)));
660      return;
661    }
662
663    // Create a operand placeholder to always yield the same number of operands.
664    Inst.addOperand(MCOperand::CreateReg(0));
665
666    // FIXME: #-0 is encoded differently than #0. Does the parser preserve
667    // the difference?
668    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
669    assert(CE && "Non-constant mode 2 offset operand!");
670    int64_t Offset = CE->getValue();
671
672    if (Offset >= 0)
673      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::add,
674                                           Offset, ARM_AM::no_shift, IdxMode)));
675    else
676      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::sub,
677                                          -Offset, ARM_AM::no_shift, IdxMode)));
678  }
679
680  void addMemMode3Operands(MCInst &Inst, unsigned N) const {
681    assert(isMemMode3() && "Invalid mode or number of operands!");
682    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
683    unsigned IdxMode = (getMemPreindexed() | getMemPostindexed() << 1);
684
685    if (getMemOffsetIsReg()) {
686      Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum()));
687
688      ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : ARM_AM::add;
689      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM3Opc(AMOpc, 0,
690                                                             IdxMode)));
691      return;
692    }
693
694    // Create a operand placeholder to always yield the same number of operands.
695    Inst.addOperand(MCOperand::CreateReg(0));
696
697    // FIXME: #-0 is encoded differently than #0. Does the parser preserve
698    // the difference?
699    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
700    assert(CE && "Non-constant mode 3 offset operand!");
701    int64_t Offset = CE->getValue();
702
703    if (Offset >= 0)
704      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM3Opc(ARM_AM::add,
705                                           Offset, IdxMode)));
706    else
707      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM3Opc(ARM_AM::sub,
708                                           -Offset, IdxMode)));
709  }
710
711  void addMemMode5Operands(MCInst &Inst, unsigned N) const {
712    assert(N == 2 && isMemMode5() && "Invalid number of operands!");
713
714    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
715    assert(!getMemOffsetIsReg() && "Invalid mode 5 operand");
716
717    // FIXME: #-0 is encoded differently than #0. Does the parser preserve
718    // the difference?
719    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
720    assert(CE && "Non-constant mode 5 offset operand!");
721
722    // The MCInst offset operand doesn't include the low two bits (like
723    // the instruction encoding).
724    int64_t Offset = CE->getValue() / 4;
725    if (Offset >= 0)
726      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::add,
727                                                             Offset)));
728    else
729      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::sub,
730                                                             -Offset)));
731  }
732
733  void addMemModeRegThumbOperands(MCInst &Inst, unsigned N) const {
734    assert(N == 2 && isMemModeRegThumb() && "Invalid number of operands!");
735    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
736    Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum()));
737  }
738
739  void addMemModeImmThumbOperands(MCInst &Inst, unsigned N) const {
740    assert(N == 2 && isMemModeImmThumb() && "Invalid number of operands!");
741    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
742    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
743    assert(CE && "Non-constant mode offset operand!");
744    Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
745  }
746
747  void addMSRMaskOperands(MCInst &Inst, unsigned N) const {
748    assert(N == 1 && "Invalid number of operands!");
749    Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask())));
750  }
751
752  void addProcIFlagsOperands(MCInst &Inst, unsigned N) const {
753    assert(N == 1 && "Invalid number of operands!");
754    Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags())));
755  }
756
757  virtual void print(raw_ostream &OS) const;
758
759  static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) {
760    ARMOperand *Op = new ARMOperand(CondCode);
761    Op->CC.Val = CC;
762    Op->StartLoc = S;
763    Op->EndLoc = S;
764    return Op;
765  }
766
767  static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) {
768    ARMOperand *Op = new ARMOperand(CoprocNum);
769    Op->Cop.Val = CopVal;
770    Op->StartLoc = S;
771    Op->EndLoc = S;
772    return Op;
773  }
774
775  static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) {
776    ARMOperand *Op = new ARMOperand(CoprocReg);
777    Op->Cop.Val = CopVal;
778    Op->StartLoc = S;
779    Op->EndLoc = S;
780    return Op;
781  }
782
783  static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) {
784    ARMOperand *Op = new ARMOperand(CCOut);
785    Op->Reg.RegNum = RegNum;
786    Op->StartLoc = S;
787    Op->EndLoc = S;
788    return Op;
789  }
790
791  static ARMOperand *CreateToken(StringRef Str, SMLoc S) {
792    ARMOperand *Op = new ARMOperand(Token);
793    Op->Tok.Data = Str.data();
794    Op->Tok.Length = Str.size();
795    Op->StartLoc = S;
796    Op->EndLoc = S;
797    return Op;
798  }
799
800  static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
801    ARMOperand *Op = new ARMOperand(Register);
802    Op->Reg.RegNum = RegNum;
803    Op->StartLoc = S;
804    Op->EndLoc = E;
805    return Op;
806  }
807
808  static ARMOperand *CreateShiftedRegister(ARM_AM::ShiftOpc ShTy,
809                                           unsigned SrcReg,
810                                           unsigned ShiftReg,
811                                           unsigned ShiftImm,
812                                           SMLoc S, SMLoc E) {
813    ARMOperand *Op = new ARMOperand(ShiftedRegister);
814    Op->ShiftedReg.ShiftTy = ShTy;
815    Op->ShiftedReg.SrcReg = SrcReg;
816    Op->ShiftedReg.ShiftReg = ShiftReg;
817    Op->ShiftedReg.ShiftImm = ShiftImm;
818    Op->StartLoc = S;
819    Op->EndLoc = E;
820    return Op;
821  }
822
823  static ARMOperand *CreateShifter(ARM_AM::ShiftOpc ShTy,
824                                   SMLoc S, SMLoc E) {
825    ARMOperand *Op = new ARMOperand(Shifter);
826    Op->Shift.ShiftTy = ShTy;
827    Op->StartLoc = S;
828    Op->EndLoc = E;
829    return Op;
830  }
831
832  static ARMOperand *
833  CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs,
834                SMLoc StartLoc, SMLoc EndLoc) {
835    KindTy Kind = RegisterList;
836
837    if (ARM::DPRRegClass.contains(Regs.front().first))
838      Kind = DPRRegisterList;
839    else if (ARM::SPRRegClass.contains(Regs.front().first))
840      Kind = SPRRegisterList;
841
842    ARMOperand *Op = new ARMOperand(Kind);
843    for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator
844           I = Regs.begin(), E = Regs.end(); I != E; ++I)
845      Op->Registers.push_back(I->first);
846    array_pod_sort(Op->Registers.begin(), Op->Registers.end());
847    Op->StartLoc = StartLoc;
848    Op->EndLoc = EndLoc;
849    return Op;
850  }
851
852  static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
853    ARMOperand *Op = new ARMOperand(Immediate);
854    Op->Imm.Val = Val;
855    Op->StartLoc = S;
856    Op->EndLoc = E;
857    return Op;
858  }
859
860  static ARMOperand *CreateMem(ARMII::AddrMode AddrMode, unsigned BaseRegNum,
861                               bool OffsetIsReg, const MCExpr *Offset,
862                               int OffsetRegNum, bool OffsetRegShifted,
863                               enum ARM_AM::ShiftOpc ShiftType,
864                               const MCExpr *ShiftAmount, bool Preindexed,
865                               bool Postindexed, bool Negative, bool Writeback,
866                               SMLoc S, SMLoc E) {
867    assert((OffsetRegNum == -1 || OffsetIsReg) &&
868           "OffsetRegNum must imply OffsetIsReg!");
869    assert((!OffsetRegShifted || OffsetIsReg) &&
870           "OffsetRegShifted must imply OffsetIsReg!");
871    assert((Offset || OffsetIsReg) &&
872           "Offset must exists unless register offset is used!");
873    assert((!ShiftAmount || (OffsetIsReg && OffsetRegShifted)) &&
874           "Cannot have shift amount without shifted register offset!");
875    assert((!Offset || !OffsetIsReg) &&
876           "Cannot have expression offset and register offset!");
877
878    ARMOperand *Op = new ARMOperand(Memory);
879    Op->Mem.AddrMode = AddrMode;
880    Op->Mem.BaseRegNum = BaseRegNum;
881    Op->Mem.OffsetIsReg = OffsetIsReg;
882    if (OffsetIsReg)
883      Op->Mem.Offset.RegNum = OffsetRegNum;
884    else
885      Op->Mem.Offset.Value = Offset;
886    Op->Mem.OffsetRegShifted = OffsetRegShifted;
887    Op->Mem.ShiftType = ShiftType;
888    Op->Mem.ShiftAmount = ShiftAmount;
889    Op->Mem.Preindexed = Preindexed;
890    Op->Mem.Postindexed = Postindexed;
891    Op->Mem.Negative = Negative;
892    Op->Mem.Writeback = Writeback;
893
894    Op->StartLoc = S;
895    Op->EndLoc = E;
896    return Op;
897  }
898
899  static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) {
900    ARMOperand *Op = new ARMOperand(MemBarrierOpt);
901    Op->MBOpt.Val = Opt;
902    Op->StartLoc = S;
903    Op->EndLoc = S;
904    return Op;
905  }
906
907  static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) {
908    ARMOperand *Op = new ARMOperand(ProcIFlags);
909    Op->IFlags.Val = IFlags;
910    Op->StartLoc = S;
911    Op->EndLoc = S;
912    return Op;
913  }
914
915  static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) {
916    ARMOperand *Op = new ARMOperand(MSRMask);
917    Op->MMask.Val = MMask;
918    Op->StartLoc = S;
919    Op->EndLoc = S;
920    return Op;
921  }
922};
923
924} // end anonymous namespace.
925
926void ARMOperand::print(raw_ostream &OS) const {
927  switch (Kind) {
928  case CondCode:
929    OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">";
930    break;
931  case CCOut:
932    OS << "<ccout " << getReg() << ">";
933    break;
934  case CoprocNum:
935    OS << "<coprocessor number: " << getCoproc() << ">";
936    break;
937  case CoprocReg:
938    OS << "<coprocessor register: " << getCoproc() << ">";
939    break;
940  case MSRMask:
941    OS << "<mask: " << getMSRMask() << ">";
942    break;
943  case Immediate:
944    getImm()->print(OS);
945    break;
946  case MemBarrierOpt:
947    OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">";
948    break;
949  case Memory:
950    OS << "<memory "
951       << "am:" << ARMII::AddrModeToString(getMemAddrMode())
952       << " base:" << getMemBaseRegNum();
953    if (getMemOffsetIsReg()) {
954      OS << " offset:<register " << getMemOffsetRegNum();
955      if (getMemOffsetRegShifted()) {
956        OS << " offset-shift-type:" << getMemShiftType();
957        OS << " offset-shift-amount:" << *getMemShiftAmount();
958      }
959    } else {
960      OS << " offset:" << *getMemOffset();
961    }
962    if (getMemOffsetIsReg())
963      OS << " (offset-is-reg)";
964    if (getMemPreindexed())
965      OS << " (pre-indexed)";
966    if (getMemPostindexed())
967      OS << " (post-indexed)";
968    if (getMemNegative())
969      OS << " (negative)";
970    if (getMemWriteback())
971      OS << " (writeback)";
972    OS << ">";
973    break;
974  case ProcIFlags: {
975    OS << "<ARM_PROC::";
976    unsigned IFlags = getProcIFlags();
977    for (int i=2; i >= 0; --i)
978      if (IFlags & (1 << i))
979        OS << ARM_PROC::IFlagsToString(1 << i);
980    OS << ">";
981    break;
982  }
983  case Register:
984    OS << "<register " << getReg() << ">";
985    break;
986  case Shifter:
987    OS << "<shifter " << ARM_AM::getShiftOpcStr(Shift.ShiftTy) << ">";
988    break;
989  case ShiftedRegister:
990    OS << "<so_reg"
991       << ShiftedReg.SrcReg
992       << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(ShiftedReg.ShiftImm))
993       << ", " << ShiftedReg.ShiftReg << ", "
994       << ARM_AM::getSORegOffset(ShiftedReg.ShiftImm)
995       << ">";
996    break;
997  case RegisterList:
998  case DPRRegisterList:
999  case SPRRegisterList: {
1000    OS << "<register_list ";
1001
1002    const SmallVectorImpl<unsigned> &RegList = getRegList();
1003    for (SmallVectorImpl<unsigned>::const_iterator
1004           I = RegList.begin(), E = RegList.end(); I != E; ) {
1005      OS << *I;
1006      if (++I < E) OS << ", ";
1007    }
1008
1009    OS << ">";
1010    break;
1011  }
1012  case Token:
1013    OS << "'" << getToken() << "'";
1014    break;
1015  }
1016}
1017
1018/// @name Auto-generated Match Functions
1019/// {
1020
1021static unsigned MatchRegisterName(StringRef Name);
1022
1023/// }
1024
1025bool ARMAsmParser::ParseRegister(unsigned &RegNo,
1026                                 SMLoc &StartLoc, SMLoc &EndLoc) {
1027  RegNo = TryParseRegister();
1028
1029  return (RegNo == (unsigned)-1);
1030}
1031
1032/// Try to parse a register name.  The token must be an Identifier when called,
1033/// and if it is a register name the token is eaten and the register number is
1034/// returned.  Otherwise return -1.
1035///
1036int ARMAsmParser::TryParseRegister() {
1037  const AsmToken &Tok = Parser.getTok();
1038  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1039
1040  // FIXME: Validate register for the current architecture; we have to do
1041  // validation later, so maybe there is no need for this here.
1042  std::string upperCase = Tok.getString().str();
1043  std::string lowerCase = LowercaseString(upperCase);
1044  unsigned RegNum = MatchRegisterName(lowerCase);
1045  if (!RegNum) {
1046    RegNum = StringSwitch<unsigned>(lowerCase)
1047      .Case("r13", ARM::SP)
1048      .Case("r14", ARM::LR)
1049      .Case("r15", ARM::PC)
1050      .Case("ip", ARM::R12)
1051      .Default(0);
1052  }
1053  if (!RegNum) return -1;
1054
1055  Parser.Lex(); // Eat identifier token.
1056  return RegNum;
1057}
1058
1059// Try to parse a shifter  (e.g., "lsl <amt>"). On success, return 0.
1060// If a recoverable error occurs, return 1. If an irrecoverable error
1061// occurs, return -1. An irrecoverable error is one where tokens have been
1062// consumed in the process of trying to parse the shifter (i.e., when it is
1063// indeed a shifter operand, but malformed).
1064int ARMAsmParser::TryParseShiftRegister(
1065                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1066  SMLoc S = Parser.getTok().getLoc();
1067  const AsmToken &Tok = Parser.getTok();
1068  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1069
1070  std::string upperCase = Tok.getString().str();
1071  std::string lowerCase = LowercaseString(upperCase);
1072  ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase)
1073      .Case("lsl", ARM_AM::lsl)
1074      .Case("lsr", ARM_AM::lsr)
1075      .Case("asr", ARM_AM::asr)
1076      .Case("ror", ARM_AM::ror)
1077      .Case("rrx", ARM_AM::rrx)
1078      .Default(ARM_AM::no_shift);
1079
1080  if (ShiftTy == ARM_AM::no_shift)
1081    return 1;
1082
1083  Parser.Lex(); // Eat the operator.
1084
1085  // The source register for the shift has already been added to the
1086  // operand list, so we need to pop it off and combine it into the shifted
1087  // register operand instead.
1088  OwningPtr<ARMOperand> PrevOp((ARMOperand*)Operands.pop_back_val());
1089  if (!PrevOp->isReg())
1090    return Error(PrevOp->getStartLoc(), "shift must be of a register");
1091  int SrcReg = PrevOp->getReg();
1092  int64_t Imm = 0;
1093  int ShiftReg = 0;
1094  if (ShiftTy == ARM_AM::rrx) {
1095    // RRX Doesn't have an explicit shift amount. The encoder expects
1096    // the shift register to be the same as the source register. Seems odd,
1097    // but OK.
1098    ShiftReg = SrcReg;
1099  } else {
1100    // Figure out if this is shifted by a constant or a register (for non-RRX).
1101    if (Parser.getTok().is(AsmToken::Hash)) {
1102      Parser.Lex(); // Eat hash.
1103      SMLoc ImmLoc = Parser.getTok().getLoc();
1104      const MCExpr *ShiftExpr = 0;
1105      if (getParser().ParseExpression(ShiftExpr)) {
1106        Error(ImmLoc, "invalid immediate shift value");
1107        return -1;
1108      }
1109      // The expression must be evaluatable as an immediate.
1110      const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr);
1111      if (!CE) {
1112        Error(ImmLoc, "invalid immediate shift value");
1113        return -1;
1114      }
1115      // Range check the immediate.
1116      // lsl, ror: 0 <= imm <= 31
1117      // lsr, asr: 0 <= imm <= 32
1118      Imm = CE->getValue();
1119      if (Imm < 0 ||
1120          ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) ||
1121          ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) {
1122        Error(ImmLoc, "immediate shift value out of range");
1123        return -1;
1124      }
1125    } else if (Parser.getTok().is(AsmToken::Identifier)) {
1126      ShiftReg = TryParseRegister();
1127      SMLoc L = Parser.getTok().getLoc();
1128      if (ShiftReg == -1) {
1129        Error (L, "expected immediate or register in shift operand");
1130        return -1;
1131      }
1132    } else {
1133      Error (Parser.getTok().getLoc(),
1134                    "expected immediate or register in shift operand");
1135      return -1;
1136    }
1137  }
1138
1139  Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg,
1140                                                       ShiftReg, Imm,
1141                                               S, Parser.getTok().getLoc()));
1142
1143  return 0;
1144}
1145
1146
1147/// Try to parse a register name.  The token must be an Identifier when called.
1148/// If it's a register, an AsmOperand is created. Another AsmOperand is created
1149/// if there is a "writeback". 'true' if it's not a register.
1150///
1151/// TODO this is likely to change to allow different register types and or to
1152/// parse for a specific register type.
1153bool ARMAsmParser::
1154TryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1155  SMLoc S = Parser.getTok().getLoc();
1156  int RegNo = TryParseRegister();
1157  if (RegNo == -1)
1158    return true;
1159
1160  Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc()));
1161
1162  const AsmToken &ExclaimTok = Parser.getTok();
1163  if (ExclaimTok.is(AsmToken::Exclaim)) {
1164    Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(),
1165                                               ExclaimTok.getLoc()));
1166    Parser.Lex(); // Eat exclaim token
1167  }
1168
1169  return false;
1170}
1171
1172/// MatchCoprocessorOperandName - Try to parse an coprocessor related
1173/// instruction with a symbolic operand name. Example: "p1", "p7", "c3",
1174/// "c5", ...
1175static int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) {
1176  // Use the same layout as the tablegen'erated register name matcher. Ugly,
1177  // but efficient.
1178  switch (Name.size()) {
1179  default: break;
1180  case 2:
1181    if (Name[0] != CoprocOp)
1182      return -1;
1183    switch (Name[1]) {
1184    default:  return -1;
1185    case '0': return 0;
1186    case '1': return 1;
1187    case '2': return 2;
1188    case '3': return 3;
1189    case '4': return 4;
1190    case '5': return 5;
1191    case '6': return 6;
1192    case '7': return 7;
1193    case '8': return 8;
1194    case '9': return 9;
1195    }
1196    break;
1197  case 3:
1198    if (Name[0] != CoprocOp || Name[1] != '1')
1199      return -1;
1200    switch (Name[2]) {
1201    default:  return -1;
1202    case '0': return 10;
1203    case '1': return 11;
1204    case '2': return 12;
1205    case '3': return 13;
1206    case '4': return 14;
1207    case '5': return 15;
1208    }
1209    break;
1210  }
1211
1212  return -1;
1213}
1214
1215/// tryParseCoprocNumOperand - Try to parse an coprocessor number operand. The
1216/// token must be an Identifier when called, and if it is a coprocessor
1217/// number, the token is eaten and the operand is added to the operand list.
1218ARMAsmParser::OperandMatchResultTy ARMAsmParser::
1219tryParseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1220  SMLoc S = Parser.getTok().getLoc();
1221  const AsmToken &Tok = Parser.getTok();
1222  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1223
1224  int Num = MatchCoprocessorOperandName(Tok.getString(), 'p');
1225  if (Num == -1)
1226    return MatchOperand_NoMatch;
1227
1228  Parser.Lex(); // Eat identifier token.
1229  Operands.push_back(ARMOperand::CreateCoprocNum(Num, S));
1230  return MatchOperand_Success;
1231}
1232
1233/// tryParseCoprocRegOperand - Try to parse an coprocessor register operand. The
1234/// token must be an Identifier when called, and if it is a coprocessor
1235/// number, the token is eaten and the operand is added to the operand list.
1236ARMAsmParser::OperandMatchResultTy ARMAsmParser::
1237tryParseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1238  SMLoc S = Parser.getTok().getLoc();
1239  const AsmToken &Tok = Parser.getTok();
1240  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1241
1242  int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c');
1243  if (Reg == -1)
1244    return MatchOperand_NoMatch;
1245
1246  Parser.Lex(); // Eat identifier token.
1247  Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S));
1248  return MatchOperand_Success;
1249}
1250
1251/// Parse a register list, return it if successful else return null.  The first
1252/// token must be a '{' when called.
1253bool ARMAsmParser::
1254ParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1255  assert(Parser.getTok().is(AsmToken::LCurly) &&
1256         "Token is not a Left Curly Brace");
1257  SMLoc S = Parser.getTok().getLoc();
1258
1259  // Read the rest of the registers in the list.
1260  unsigned PrevRegNum = 0;
1261  SmallVector<std::pair<unsigned, SMLoc>, 32> Registers;
1262
1263  do {
1264    bool IsRange = Parser.getTok().is(AsmToken::Minus);
1265    Parser.Lex(); // Eat non-identifier token.
1266
1267    const AsmToken &RegTok = Parser.getTok();
1268    SMLoc RegLoc = RegTok.getLoc();
1269    if (RegTok.isNot(AsmToken::Identifier)) {
1270      Error(RegLoc, "register expected");
1271      return true;
1272    }
1273
1274    int RegNum = TryParseRegister();
1275    if (RegNum == -1) {
1276      Error(RegLoc, "register expected");
1277      return true;
1278    }
1279
1280    if (IsRange) {
1281      int Reg = PrevRegNum;
1282      do {
1283        ++Reg;
1284        Registers.push_back(std::make_pair(Reg, RegLoc));
1285      } while (Reg != RegNum);
1286    } else {
1287      Registers.push_back(std::make_pair(RegNum, RegLoc));
1288    }
1289
1290    PrevRegNum = RegNum;
1291  } while (Parser.getTok().is(AsmToken::Comma) ||
1292           Parser.getTok().is(AsmToken::Minus));
1293
1294  // Process the right curly brace of the list.
1295  const AsmToken &RCurlyTok = Parser.getTok();
1296  if (RCurlyTok.isNot(AsmToken::RCurly)) {
1297    Error(RCurlyTok.getLoc(), "'}' expected");
1298    return true;
1299  }
1300
1301  SMLoc E = RCurlyTok.getLoc();
1302  Parser.Lex(); // Eat right curly brace token.
1303
1304  // Verify the register list.
1305  SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator
1306    RI = Registers.begin(), RE = Registers.end();
1307
1308  unsigned HighRegNum = getARMRegisterNumbering(RI->first);
1309  bool EmittedWarning = false;
1310
1311  DenseMap<unsigned, bool> RegMap;
1312  RegMap[HighRegNum] = true;
1313
1314  for (++RI; RI != RE; ++RI) {
1315    const std::pair<unsigned, SMLoc> &RegInfo = *RI;
1316    unsigned Reg = getARMRegisterNumbering(RegInfo.first);
1317
1318    if (RegMap[Reg]) {
1319      Error(RegInfo.second, "register duplicated in register list");
1320      return true;
1321    }
1322
1323    if (!EmittedWarning && Reg < HighRegNum)
1324      Warning(RegInfo.second,
1325              "register not in ascending order in register list");
1326
1327    RegMap[Reg] = true;
1328    HighRegNum = std::max(Reg, HighRegNum);
1329  }
1330
1331  Operands.push_back(ARMOperand::CreateRegList(Registers, S, E));
1332  return false;
1333}
1334
1335/// tryParseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options.
1336ARMAsmParser::OperandMatchResultTy ARMAsmParser::
1337tryParseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1338  SMLoc S = Parser.getTok().getLoc();
1339  const AsmToken &Tok = Parser.getTok();
1340  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1341  StringRef OptStr = Tok.getString();
1342
1343  unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size()))
1344    .Case("sy",    ARM_MB::SY)
1345    .Case("st",    ARM_MB::ST)
1346    .Case("sh",    ARM_MB::ISH)
1347    .Case("ish",   ARM_MB::ISH)
1348    .Case("shst",  ARM_MB::ISHST)
1349    .Case("ishst", ARM_MB::ISHST)
1350    .Case("nsh",   ARM_MB::NSH)
1351    .Case("un",    ARM_MB::NSH)
1352    .Case("nshst", ARM_MB::NSHST)
1353    .Case("unst",  ARM_MB::NSHST)
1354    .Case("osh",   ARM_MB::OSH)
1355    .Case("oshst", ARM_MB::OSHST)
1356    .Default(~0U);
1357
1358  if (Opt == ~0U)
1359    return MatchOperand_NoMatch;
1360
1361  Parser.Lex(); // Eat identifier token.
1362  Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S));
1363  return MatchOperand_Success;
1364}
1365
1366/// tryParseProcIFlagsOperand - Try to parse iflags from CPS instruction.
1367ARMAsmParser::OperandMatchResultTy ARMAsmParser::
1368tryParseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1369  SMLoc S = Parser.getTok().getLoc();
1370  const AsmToken &Tok = Parser.getTok();
1371  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1372  StringRef IFlagsStr = Tok.getString();
1373
1374  unsigned IFlags = 0;
1375  for (int i = 0, e = IFlagsStr.size(); i != e; ++i) {
1376    unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1))
1377    .Case("a", ARM_PROC::A)
1378    .Case("i", ARM_PROC::I)
1379    .Case("f", ARM_PROC::F)
1380    .Default(~0U);
1381
1382    // If some specific iflag is already set, it means that some letter is
1383    // present more than once, this is not acceptable.
1384    if (Flag == ~0U || (IFlags & Flag))
1385      return MatchOperand_NoMatch;
1386
1387    IFlags |= Flag;
1388  }
1389
1390  Parser.Lex(); // Eat identifier token.
1391  Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S));
1392  return MatchOperand_Success;
1393}
1394
1395/// tryParseMSRMaskOperand - Try to parse mask flags from MSR instruction.
1396ARMAsmParser::OperandMatchResultTy ARMAsmParser::
1397tryParseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1398  SMLoc S = Parser.getTok().getLoc();
1399  const AsmToken &Tok = Parser.getTok();
1400  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1401  StringRef Mask = Tok.getString();
1402
1403  // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf"
1404  size_t Start = 0, Next = Mask.find('_');
1405  StringRef Flags = "";
1406  StringRef SpecReg = Mask.slice(Start, Next);
1407  if (Next != StringRef::npos)
1408    Flags = Mask.slice(Next+1, Mask.size());
1409
1410  // FlagsVal contains the complete mask:
1411  // 3-0: Mask
1412  // 4: Special Reg (cpsr, apsr => 0; spsr => 1)
1413  unsigned FlagsVal = 0;
1414
1415  if (SpecReg == "apsr") {
1416    FlagsVal = StringSwitch<unsigned>(Flags)
1417    .Case("nzcvq",  0x8) // same as CPSR_c
1418    .Case("g",      0x4) // same as CPSR_s
1419    .Case("nzcvqg", 0xc) // same as CPSR_fs
1420    .Default(~0U);
1421
1422    if (FlagsVal == ~0U) {
1423      if (!Flags.empty())
1424        return MatchOperand_NoMatch;
1425      else
1426        FlagsVal = 0; // No flag
1427    }
1428  } else if (SpecReg == "cpsr" || SpecReg == "spsr") {
1429    if (Flags == "all") // cpsr_all is an alias for cpsr_fc
1430      Flags = "fc";
1431    for (int i = 0, e = Flags.size(); i != e; ++i) {
1432      unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1))
1433      .Case("c", 1)
1434      .Case("x", 2)
1435      .Case("s", 4)
1436      .Case("f", 8)
1437      .Default(~0U);
1438
1439      // If some specific flag is already set, it means that some letter is
1440      // present more than once, this is not acceptable.
1441      if (FlagsVal == ~0U || (FlagsVal & Flag))
1442        return MatchOperand_NoMatch;
1443      FlagsVal |= Flag;
1444    }
1445  } else // No match for special register.
1446    return MatchOperand_NoMatch;
1447
1448  // Special register without flags are equivalent to "fc" flags.
1449  if (!FlagsVal)
1450    FlagsVal = 0x9;
1451
1452  // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1)
1453  if (SpecReg == "spsr")
1454    FlagsVal |= 16;
1455
1456  Parser.Lex(); // Eat identifier token.
1457  Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
1458  return MatchOperand_Success;
1459}
1460
1461/// tryParseMemMode2Operand - Try to parse memory addressing mode 2 operand.
1462ARMAsmParser::OperandMatchResultTy ARMAsmParser::
1463tryParseMemMode2Operand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1464  assert(Parser.getTok().is(AsmToken::LBrac) && "Token is not a \"[\"");
1465
1466  if (ParseMemory(Operands, ARMII::AddrMode2))
1467    return MatchOperand_NoMatch;
1468
1469  return MatchOperand_Success;
1470}
1471
1472/// tryParseMemMode3Operand - Try to parse memory addressing mode 3 operand.
1473ARMAsmParser::OperandMatchResultTy ARMAsmParser::
1474tryParseMemMode3Operand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1475  assert(Parser.getTok().is(AsmToken::LBrac) && "Token is not a \"[\"");
1476
1477  if (ParseMemory(Operands, ARMII::AddrMode3))
1478    return MatchOperand_NoMatch;
1479
1480  return MatchOperand_Success;
1481}
1482
1483/// CvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
1484/// Needed here because the Asm Gen Matcher can't handle properly tied operands
1485/// when they refer multiple MIOperands inside a single one.
1486bool ARMAsmParser::
1487CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
1488                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1489  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
1490
1491  // Create a writeback register dummy placeholder.
1492  Inst.addOperand(MCOperand::CreateImm(0));
1493
1494  ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3);
1495  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
1496  return true;
1497}
1498
1499/// CvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
1500/// Needed here because the Asm Gen Matcher can't handle properly tied operands
1501/// when they refer multiple MIOperands inside a single one.
1502bool ARMAsmParser::
1503CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
1504                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1505  // Create a writeback register dummy placeholder.
1506  Inst.addOperand(MCOperand::CreateImm(0));
1507  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
1508  ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3);
1509  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
1510  return true;
1511}
1512
1513/// CvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
1514/// Needed here because the Asm Gen Matcher can't handle properly tied operands
1515/// when they refer multiple MIOperands inside a single one.
1516bool ARMAsmParser::
1517CvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
1518                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1519  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
1520
1521  // Create a writeback register dummy placeholder.
1522  Inst.addOperand(MCOperand::CreateImm(0));
1523
1524  ((ARMOperand*)Operands[3])->addMemMode3Operands(Inst, 3);
1525  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
1526  return true;
1527}
1528
1529/// CvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
1530/// Needed here because the Asm Gen Matcher can't handle properly tied operands
1531/// when they refer multiple MIOperands inside a single one.
1532bool ARMAsmParser::
1533CvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
1534                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1535  // Create a writeback register dummy placeholder.
1536  Inst.addOperand(MCOperand::CreateImm(0));
1537  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
1538  ((ARMOperand*)Operands[3])->addMemMode3Operands(Inst, 3);
1539  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
1540  return true;
1541}
1542
1543/// Parse an ARM memory expression, return false if successful else return true
1544/// or an error.  The first token must be a '[' when called.
1545///
1546/// TODO Only preindexing and postindexing addressing are started, unindexed
1547/// with option, etc are still to do.
1548bool ARMAsmParser::
1549ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1550            ARMII::AddrMode AddrMode = ARMII::AddrModeNone) {
1551  SMLoc S, E;
1552  assert(Parser.getTok().is(AsmToken::LBrac) &&
1553         "Token is not a Left Bracket");
1554  S = Parser.getTok().getLoc();
1555  Parser.Lex(); // Eat left bracket token.
1556
1557  const AsmToken &BaseRegTok = Parser.getTok();
1558  if (BaseRegTok.isNot(AsmToken::Identifier)) {
1559    Error(BaseRegTok.getLoc(), "register expected");
1560    return true;
1561  }
1562  int BaseRegNum = TryParseRegister();
1563  if (BaseRegNum == -1) {
1564    Error(BaseRegTok.getLoc(), "register expected");
1565    return true;
1566  }
1567
1568  // The next token must either be a comma or a closing bracket.
1569  const AsmToken &Tok = Parser.getTok();
1570  if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac))
1571    return true;
1572
1573  bool Preindexed = false;
1574  bool Postindexed = false;
1575  bool OffsetIsReg = false;
1576  bool Negative = false;
1577  bool Writeback = false;
1578  ARMOperand *WBOp = 0;
1579  int OffsetRegNum = -1;
1580  bool OffsetRegShifted = false;
1581  enum ARM_AM::ShiftOpc ShiftType = ARM_AM::lsl;
1582  const MCExpr *ShiftAmount = 0;
1583  const MCExpr *Offset = 0;
1584
1585  // First look for preindexed address forms, that is after the "[Rn" we now
1586  // have to see if the next token is a comma.
1587  if (Tok.is(AsmToken::Comma)) {
1588    Preindexed = true;
1589    Parser.Lex(); // Eat comma token.
1590
1591    if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, ShiftAmount,
1592                             Offset, OffsetIsReg, OffsetRegNum, E))
1593      return true;
1594    const AsmToken &RBracTok = Parser.getTok();
1595    if (RBracTok.isNot(AsmToken::RBrac)) {
1596      Error(RBracTok.getLoc(), "']' expected");
1597      return true;
1598    }
1599    E = RBracTok.getLoc();
1600    Parser.Lex(); // Eat right bracket token.
1601
1602    const AsmToken &ExclaimTok = Parser.getTok();
1603    if (ExclaimTok.is(AsmToken::Exclaim)) {
1604      // None of addrmode3 instruction uses "!"
1605      if (AddrMode == ARMII::AddrMode3)
1606        return true;
1607
1608      WBOp = ARMOperand::CreateToken(ExclaimTok.getString(),
1609                                     ExclaimTok.getLoc());
1610      Writeback = true;
1611      Parser.Lex(); // Eat exclaim token
1612    } else { // In addressing mode 2, pre-indexed mode always end with "!"
1613      if (AddrMode == ARMII::AddrMode2)
1614        Preindexed = false;
1615    }
1616  } else {
1617    // The "[Rn" we have so far was not followed by a comma.
1618
1619    // If there's anything other than the right brace, this is a post indexing
1620    // addressing form.
1621    E = Tok.getLoc();
1622    Parser.Lex(); // Eat right bracket token.
1623
1624    const AsmToken &NextTok = Parser.getTok();
1625
1626    if (NextTok.isNot(AsmToken::EndOfStatement)) {
1627      Postindexed = true;
1628      Writeback = true;
1629
1630      if (NextTok.isNot(AsmToken::Comma)) {
1631        Error(NextTok.getLoc(), "',' expected");
1632        return true;
1633      }
1634
1635      Parser.Lex(); // Eat comma token.
1636
1637      if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType,
1638                               ShiftAmount, Offset, OffsetIsReg, OffsetRegNum,
1639                               E))
1640        return true;
1641    }
1642  }
1643
1644  // Force Offset to exist if used.
1645  if (!OffsetIsReg) {
1646    if (!Offset)
1647      Offset = MCConstantExpr::Create(0, getContext());
1648  } else {
1649    if (AddrMode == ARMII::AddrMode3 && OffsetRegShifted) {
1650      Error(E, "shift amount not supported");
1651      return true;
1652    }
1653  }
1654
1655  Operands.push_back(ARMOperand::CreateMem(AddrMode, BaseRegNum, OffsetIsReg,
1656                                     Offset, OffsetRegNum, OffsetRegShifted,
1657                                     ShiftType, ShiftAmount, Preindexed,
1658                                     Postindexed, Negative, Writeback, S, E));
1659  if (WBOp)
1660    Operands.push_back(WBOp);
1661
1662  return false;
1663}
1664
1665/// Parse the offset of a memory operand after we have seen "[Rn," or "[Rn],"
1666/// we will parse the following (were +/- means that a plus or minus is
1667/// optional):
1668///   +/-Rm
1669///   +/-Rm, shift
1670///   #offset
1671/// we return false on success or an error otherwise.
1672bool ARMAsmParser::ParseMemoryOffsetReg(bool &Negative,
1673                                        bool &OffsetRegShifted,
1674                                        enum ARM_AM::ShiftOpc &ShiftType,
1675                                        const MCExpr *&ShiftAmount,
1676                                        const MCExpr *&Offset,
1677                                        bool &OffsetIsReg,
1678                                        int &OffsetRegNum,
1679                                        SMLoc &E) {
1680  Negative = false;
1681  OffsetRegShifted = false;
1682  OffsetIsReg = false;
1683  OffsetRegNum = -1;
1684  const AsmToken &NextTok = Parser.getTok();
1685  E = NextTok.getLoc();
1686  if (NextTok.is(AsmToken::Plus))
1687    Parser.Lex(); // Eat plus token.
1688  else if (NextTok.is(AsmToken::Minus)) {
1689    Negative = true;
1690    Parser.Lex(); // Eat minus token
1691  }
1692  // See if there is a register following the "[Rn," or "[Rn]," we have so far.
1693  const AsmToken &OffsetRegTok = Parser.getTok();
1694  if (OffsetRegTok.is(AsmToken::Identifier)) {
1695    SMLoc CurLoc = OffsetRegTok.getLoc();
1696    OffsetRegNum = TryParseRegister();
1697    if (OffsetRegNum != -1) {
1698      OffsetIsReg = true;
1699      E = CurLoc;
1700    }
1701  }
1702
1703  // If we parsed a register as the offset then there can be a shift after that.
1704  if (OffsetRegNum != -1) {
1705    // Look for a comma then a shift
1706    const AsmToken &Tok = Parser.getTok();
1707    if (Tok.is(AsmToken::Comma)) {
1708      Parser.Lex(); // Eat comma token.
1709
1710      const AsmToken &Tok = Parser.getTok();
1711      if (ParseShift(ShiftType, ShiftAmount, E))
1712        return Error(Tok.getLoc(), "shift expected");
1713      OffsetRegShifted = true;
1714    }
1715  }
1716  else { // the "[Rn," or "[Rn,]" we have so far was not followed by "Rm"
1717    // Look for #offset following the "[Rn," or "[Rn],"
1718    const AsmToken &HashTok = Parser.getTok();
1719    if (HashTok.isNot(AsmToken::Hash))
1720      return Error(HashTok.getLoc(), "'#' expected");
1721
1722    Parser.Lex(); // Eat hash token.
1723
1724    if (getParser().ParseExpression(Offset))
1725     return true;
1726    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1727  }
1728  return false;
1729}
1730
1731/// ParseShift as one of these two:
1732///   ( lsl | lsr | asr | ror ) , # shift_amount
1733///   rrx
1734/// and returns true if it parses a shift otherwise it returns false.
1735bool ARMAsmParser::ParseShift(ARM_AM::ShiftOpc &St,
1736                              const MCExpr *&ShiftAmount, SMLoc &E) {
1737  const AsmToken &Tok = Parser.getTok();
1738  if (Tok.isNot(AsmToken::Identifier))
1739    return true;
1740  StringRef ShiftName = Tok.getString();
1741  if (ShiftName == "lsl" || ShiftName == "LSL")
1742    St = ARM_AM::lsl;
1743  else if (ShiftName == "lsr" || ShiftName == "LSR")
1744    St = ARM_AM::lsr;
1745  else if (ShiftName == "asr" || ShiftName == "ASR")
1746    St = ARM_AM::asr;
1747  else if (ShiftName == "ror" || ShiftName == "ROR")
1748    St = ARM_AM::ror;
1749  else if (ShiftName == "rrx" || ShiftName == "RRX")
1750    St = ARM_AM::rrx;
1751  else
1752    return true;
1753  Parser.Lex(); // Eat shift type token.
1754
1755  // Rrx stands alone.
1756  if (St == ARM_AM::rrx)
1757    return false;
1758
1759  // Otherwise, there must be a '#' and a shift amount.
1760  const AsmToken &HashTok = Parser.getTok();
1761  if (HashTok.isNot(AsmToken::Hash))
1762    return Error(HashTok.getLoc(), "'#' expected");
1763  Parser.Lex(); // Eat hash token.
1764
1765  if (getParser().ParseExpression(ShiftAmount))
1766    return true;
1767
1768  return false;
1769}
1770
1771/// Parse a arm instruction operand.  For now this parses the operand regardless
1772/// of the mnemonic.
1773bool ARMAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1774                                StringRef Mnemonic) {
1775  SMLoc S, E;
1776
1777  // Check if the current operand has a custom associated parser, if so, try to
1778  // custom parse the operand, or fallback to the general approach.
1779  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1780  if (ResTy == MatchOperand_Success)
1781    return false;
1782  // If there wasn't a custom match, try the generic matcher below. Otherwise,
1783  // there was a match, but an error occurred, in which case, just return that
1784  // the operand parsing failed.
1785  if (ResTy == MatchOperand_ParseFail)
1786    return true;
1787
1788  switch (getLexer().getKind()) {
1789  default:
1790    Error(Parser.getTok().getLoc(), "unexpected token in operand");
1791    return true;
1792  case AsmToken::Identifier: {
1793    if (!TryParseRegisterWithWriteBack(Operands))
1794      return false;
1795    int Res = TryParseShiftRegister(Operands);
1796    if (Res == 0) // success
1797      return false;
1798    else if (Res == -1) // irrecoverable error
1799      return true;
1800
1801    // Fall though for the Identifier case that is not a register or a
1802    // special name.
1803  }
1804  case AsmToken::Integer: // things like 1f and 2b as a branch targets
1805  case AsmToken::Dot: {   // . as a branch target
1806    // This was not a register so parse other operands that start with an
1807    // identifier (like labels) as expressions and create them as immediates.
1808    const MCExpr *IdVal;
1809    S = Parser.getTok().getLoc();
1810    if (getParser().ParseExpression(IdVal))
1811      return true;
1812    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1813    Operands.push_back(ARMOperand::CreateImm(IdVal, S, E));
1814    return false;
1815  }
1816  case AsmToken::LBrac:
1817    return ParseMemory(Operands);
1818  case AsmToken::LCurly:
1819    return ParseRegisterList(Operands);
1820  case AsmToken::Hash:
1821    // #42 -> immediate.
1822    // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate
1823    S = Parser.getTok().getLoc();
1824    Parser.Lex();
1825    const MCExpr *ImmVal;
1826    if (getParser().ParseExpression(ImmVal))
1827      return true;
1828    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1829    Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E));
1830    return false;
1831  case AsmToken::Colon: {
1832    // ":lower16:" and ":upper16:" expression prefixes
1833    // FIXME: Check it's an expression prefix,
1834    // e.g. (FOO - :lower16:BAR) isn't legal.
1835    ARMMCExpr::VariantKind RefKind;
1836    if (ParsePrefix(RefKind))
1837      return true;
1838
1839    const MCExpr *SubExprVal;
1840    if (getParser().ParseExpression(SubExprVal))
1841      return true;
1842
1843    const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal,
1844                                                   getContext());
1845    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1846    Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E));
1847    return false;
1848  }
1849  }
1850}
1851
1852// ParsePrefix - Parse ARM 16-bit relocations expression prefix, i.e.
1853//  :lower16: and :upper16:.
1854bool ARMAsmParser::ParsePrefix(ARMMCExpr::VariantKind &RefKind) {
1855  RefKind = ARMMCExpr::VK_ARM_None;
1856
1857  // :lower16: and :upper16: modifiers
1858  assert(getLexer().is(AsmToken::Colon) && "expected a :");
1859  Parser.Lex(); // Eat ':'
1860
1861  if (getLexer().isNot(AsmToken::Identifier)) {
1862    Error(Parser.getTok().getLoc(), "expected prefix identifier in operand");
1863    return true;
1864  }
1865
1866  StringRef IDVal = Parser.getTok().getIdentifier();
1867  if (IDVal == "lower16") {
1868    RefKind = ARMMCExpr::VK_ARM_LO16;
1869  } else if (IDVal == "upper16") {
1870    RefKind = ARMMCExpr::VK_ARM_HI16;
1871  } else {
1872    Error(Parser.getTok().getLoc(), "unexpected prefix in operand");
1873    return true;
1874  }
1875  Parser.Lex();
1876
1877  if (getLexer().isNot(AsmToken::Colon)) {
1878    Error(Parser.getTok().getLoc(), "unexpected token after prefix");
1879    return true;
1880  }
1881  Parser.Lex(); // Eat the last ':'
1882  return false;
1883}
1884
1885const MCExpr *
1886ARMAsmParser::ApplyPrefixToExpr(const MCExpr *E,
1887                                MCSymbolRefExpr::VariantKind Variant) {
1888  // Recurse over the given expression, rebuilding it to apply the given variant
1889  // to the leftmost symbol.
1890  if (Variant == MCSymbolRefExpr::VK_None)
1891    return E;
1892
1893  switch (E->getKind()) {
1894  case MCExpr::Target:
1895    llvm_unreachable("Can't handle target expr yet");
1896  case MCExpr::Constant:
1897    llvm_unreachable("Can't handle lower16/upper16 of constant yet");
1898
1899  case MCExpr::SymbolRef: {
1900    const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
1901
1902    if (SRE->getKind() != MCSymbolRefExpr::VK_None)
1903      return 0;
1904
1905    return MCSymbolRefExpr::Create(&SRE->getSymbol(), Variant, getContext());
1906  }
1907
1908  case MCExpr::Unary:
1909    llvm_unreachable("Can't handle unary expressions yet");
1910
1911  case MCExpr::Binary: {
1912    const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
1913    const MCExpr *LHS = ApplyPrefixToExpr(BE->getLHS(), Variant);
1914    const MCExpr *RHS = BE->getRHS();
1915    if (!LHS)
1916      return 0;
1917
1918    return MCBinaryExpr::Create(BE->getOpcode(), LHS, RHS, getContext());
1919  }
1920  }
1921
1922  assert(0 && "Invalid expression kind!");
1923  return 0;
1924}
1925
1926/// \brief Given a mnemonic, split out possible predication code and carry
1927/// setting letters to form a canonical mnemonic and flags.
1928//
1929// FIXME: Would be nice to autogen this.
1930static StringRef SplitMnemonic(StringRef Mnemonic,
1931                               unsigned &PredicationCode,
1932                               bool &CarrySetting,
1933                               unsigned &ProcessorIMod) {
1934  PredicationCode = ARMCC::AL;
1935  CarrySetting = false;
1936  ProcessorIMod = 0;
1937
1938  // Ignore some mnemonics we know aren't predicated forms.
1939  //
1940  // FIXME: Would be nice to autogen this.
1941  if (Mnemonic == "teq" || Mnemonic == "vceq" ||
1942      Mnemonic == "movs" ||
1943      Mnemonic == "svc" ||
1944      (Mnemonic == "mls" || Mnemonic == "smmls" || Mnemonic == "vcls" ||
1945       Mnemonic == "vmls" || Mnemonic == "vnmls") ||
1946      Mnemonic == "vacge" || Mnemonic == "vcge" ||
1947      Mnemonic == "vclt" ||
1948      Mnemonic == "vacgt" || Mnemonic == "vcgt" ||
1949      Mnemonic == "vcle" ||
1950      (Mnemonic == "smlal" || Mnemonic == "umaal" || Mnemonic == "umlal" ||
1951       Mnemonic == "vabal" || Mnemonic == "vmlal" || Mnemonic == "vpadal" ||
1952       Mnemonic == "vqdmlal" || Mnemonic == "bics"))
1953    return Mnemonic;
1954
1955  // First, split out any predication code. Ignore mnemonics we know aren't
1956  // predicated but do have a carry-set and so weren't caught above.
1957  if (Mnemonic != "adcs") {
1958    unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2))
1959      .Case("eq", ARMCC::EQ)
1960      .Case("ne", ARMCC::NE)
1961      .Case("hs", ARMCC::HS)
1962      .Case("cs", ARMCC::HS)
1963      .Case("lo", ARMCC::LO)
1964      .Case("cc", ARMCC::LO)
1965      .Case("mi", ARMCC::MI)
1966      .Case("pl", ARMCC::PL)
1967      .Case("vs", ARMCC::VS)
1968      .Case("vc", ARMCC::VC)
1969      .Case("hi", ARMCC::HI)
1970      .Case("ls", ARMCC::LS)
1971      .Case("ge", ARMCC::GE)
1972      .Case("lt", ARMCC::LT)
1973      .Case("gt", ARMCC::GT)
1974      .Case("le", ARMCC::LE)
1975      .Case("al", ARMCC::AL)
1976      .Default(~0U);
1977    if (CC != ~0U) {
1978      Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2);
1979      PredicationCode = CC;
1980    }
1981  }
1982
1983  // Next, determine if we have a carry setting bit. We explicitly ignore all
1984  // the instructions we know end in 's'.
1985  if (Mnemonic.endswith("s") &&
1986      !(Mnemonic == "asrs" || Mnemonic == "cps" || Mnemonic == "mls" ||
1987        Mnemonic == "movs" || Mnemonic == "mrs" || Mnemonic == "smmls" ||
1988        Mnemonic == "vabs" || Mnemonic == "vcls" || Mnemonic == "vmls" ||
1989        Mnemonic == "vmrs" || Mnemonic == "vnmls" || Mnemonic == "vqabs" ||
1990        Mnemonic == "vrecps" || Mnemonic == "vrsqrts")) {
1991    Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1);
1992    CarrySetting = true;
1993  }
1994
1995  // The "cps" instruction can have a interrupt mode operand which is glued into
1996  // the mnemonic. Check if this is the case, split it and parse the imod op
1997  if (Mnemonic.startswith("cps")) {
1998    // Split out any imod code.
1999    unsigned IMod =
2000      StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2))
2001      .Case("ie", ARM_PROC::IE)
2002      .Case("id", ARM_PROC::ID)
2003      .Default(~0U);
2004    if (IMod != ~0U) {
2005      Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2);
2006      ProcessorIMod = IMod;
2007    }
2008  }
2009
2010  return Mnemonic;
2011}
2012
2013/// \brief Given a canonical mnemonic, determine if the instruction ever allows
2014/// inclusion of carry set or predication code operands.
2015//
2016// FIXME: It would be nice to autogen this.
2017void ARMAsmParser::
2018GetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
2019                      bool &CanAcceptPredicationCode) {
2020  if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" ||
2021      Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" ||
2022      Mnemonic == "smull" || Mnemonic == "add" || Mnemonic == "adc" ||
2023      Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" ||
2024      Mnemonic == "umlal" || Mnemonic == "orr" || Mnemonic == "mvn" ||
2025      Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" ||
2026      Mnemonic == "sbc" || Mnemonic == "mla" || Mnemonic == "umull" ||
2027      Mnemonic == "eor" || Mnemonic == "smlal" ||
2028      (Mnemonic == "mov" && !isThumbOne())) {
2029    CanAcceptCarrySet = true;
2030  } else {
2031    CanAcceptCarrySet = false;
2032  }
2033
2034  if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" ||
2035      Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" ||
2036      Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" ||
2037      Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" ||
2038      Mnemonic == "dsb" || Mnemonic == "movs" || Mnemonic == "isb" ||
2039      Mnemonic == "clrex" || Mnemonic.startswith("cps")) {
2040    CanAcceptPredicationCode = false;
2041  } else {
2042    CanAcceptPredicationCode = true;
2043  }
2044
2045  if (isThumb())
2046    if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" ||
2047        Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp")
2048      CanAcceptPredicationCode = false;
2049}
2050
2051/// Parse an arm instruction mnemonic followed by its operands.
2052bool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc,
2053                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2054  // Create the leading tokens for the mnemonic, split by '.' characters.
2055  size_t Start = 0, Next = Name.find('.');
2056  StringRef Head = Name.slice(Start, Next);
2057
2058  // Split out the predication code and carry setting flag from the mnemonic.
2059  unsigned PredicationCode;
2060  unsigned ProcessorIMod;
2061  bool CarrySetting;
2062  Head = SplitMnemonic(Head, PredicationCode, CarrySetting,
2063                       ProcessorIMod);
2064
2065  Operands.push_back(ARMOperand::CreateToken(Head, NameLoc));
2066
2067  // Next, add the CCOut and ConditionCode operands, if needed.
2068  //
2069  // For mnemonics which can ever incorporate a carry setting bit or predication
2070  // code, our matching model involves us always generating CCOut and
2071  // ConditionCode operands to match the mnemonic "as written" and then we let
2072  // the matcher deal with finding the right instruction or generating an
2073  // appropriate error.
2074  bool CanAcceptCarrySet, CanAcceptPredicationCode;
2075  GetMnemonicAcceptInfo(Head, CanAcceptCarrySet, CanAcceptPredicationCode);
2076
2077  // Add the carry setting operand, if necessary.
2078  //
2079  // FIXME: It would be awesome if we could somehow invent a location such that
2080  // match errors on this operand would print a nice diagnostic about how the
2081  // 's' character in the mnemonic resulted in a CCOut operand.
2082  if (CanAcceptCarrySet) {
2083    Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0,
2084                                               NameLoc));
2085  } else {
2086    // This mnemonic can't ever accept a carry set, but the user wrote one (or
2087    // misspelled another mnemonic).
2088
2089    // FIXME: Issue a nice error.
2090  }
2091
2092  // Add the predication code operand, if necessary.
2093  if (CanAcceptPredicationCode) {
2094    Operands.push_back(ARMOperand::CreateCondCode(
2095                         ARMCC::CondCodes(PredicationCode), NameLoc));
2096  } else {
2097    // This mnemonic can't ever accept a predication code, but the user wrote
2098    // one (or misspelled another mnemonic).
2099
2100    // FIXME: Issue a nice error.
2101  }
2102
2103  // Add the processor imod operand, if necessary.
2104  if (ProcessorIMod) {
2105    Operands.push_back(ARMOperand::CreateImm(
2106          MCConstantExpr::Create(ProcessorIMod, getContext()),
2107                                 NameLoc, NameLoc));
2108  } else {
2109    // This mnemonic can't ever accept a imod, but the user wrote
2110    // one (or misspelled another mnemonic).
2111
2112    // FIXME: Issue a nice error.
2113  }
2114
2115  // Add the remaining tokens in the mnemonic.
2116  while (Next != StringRef::npos) {
2117    Start = Next;
2118    Next = Name.find('.', Start + 1);
2119    StringRef ExtraToken = Name.slice(Start, Next);
2120
2121    Operands.push_back(ARMOperand::CreateToken(ExtraToken, NameLoc));
2122  }
2123
2124  // Read the remaining operands.
2125  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2126    // Read the first operand.
2127    if (ParseOperand(Operands, Head)) {
2128      Parser.EatToEndOfStatement();
2129      return true;
2130    }
2131
2132    while (getLexer().is(AsmToken::Comma)) {
2133      Parser.Lex();  // Eat the comma.
2134
2135      // Parse and remember the operand.
2136      if (ParseOperand(Operands, Head)) {
2137        Parser.EatToEndOfStatement();
2138        return true;
2139      }
2140    }
2141  }
2142
2143  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2144    Parser.EatToEndOfStatement();
2145    return TokError("unexpected token in argument list");
2146  }
2147
2148  Parser.Lex(); // Consume the EndOfStatement
2149  return false;
2150}
2151
2152bool ARMAsmParser::
2153MatchAndEmitInstruction(SMLoc IDLoc,
2154                        SmallVectorImpl<MCParsedAsmOperand*> &Operands,
2155                        MCStreamer &Out) {
2156  MCInst Inst;
2157  unsigned ErrorInfo;
2158  MatchResultTy MatchResult, MatchResult2;
2159  MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo);
2160  if (MatchResult != Match_Success) {
2161    // If we get a Match_InvalidOperand it might be some arithmetic instruction
2162    // that does not update the condition codes.  So try adding a CCOut operand
2163    // with a value of reg0.
2164    if (MatchResult == Match_InvalidOperand) {
2165      Operands.insert(Operands.begin() + 1,
2166                      ARMOperand::CreateCCOut(0,
2167                                  ((ARMOperand*)Operands[0])->getStartLoc()));
2168      MatchResult2 = MatchInstructionImpl(Operands, Inst, ErrorInfo);
2169      if (MatchResult2 == Match_Success)
2170        MatchResult = Match_Success;
2171      else {
2172        ARMOperand *CCOut = ((ARMOperand*)Operands[1]);
2173        Operands.erase(Operands.begin() + 1);
2174        delete CCOut;
2175      }
2176    }
2177    // If we get a Match_MnemonicFail it might be some arithmetic instruction
2178    // that updates the condition codes if it ends in 's'.  So see if the
2179    // mnemonic ends in 's' and if so try removing the 's' and adding a CCOut
2180    // operand with a value of CPSR.
2181    else if (MatchResult == Match_MnemonicFail) {
2182      // Get the instruction mnemonic, which is the first token.
2183      StringRef Mnemonic = ((ARMOperand*)Operands[0])->getToken();
2184      if (Mnemonic.substr(Mnemonic.size()-1) == "s") {
2185        // removed the 's' from the mnemonic for matching.
2186        StringRef MnemonicNoS = Mnemonic.slice(0, Mnemonic.size() - 1);
2187        SMLoc NameLoc = ((ARMOperand*)Operands[0])->getStartLoc();
2188        ARMOperand *OldMnemonic = ((ARMOperand*)Operands[0]);
2189        Operands.erase(Operands.begin());
2190        delete OldMnemonic;
2191        Operands.insert(Operands.begin(),
2192                        ARMOperand::CreateToken(MnemonicNoS, NameLoc));
2193        Operands.insert(Operands.begin() + 1,
2194                        ARMOperand::CreateCCOut(ARM::CPSR, NameLoc));
2195        MatchResult2 = MatchInstructionImpl(Operands, Inst, ErrorInfo);
2196        if (MatchResult2 == Match_Success)
2197          MatchResult = Match_Success;
2198        else {
2199          ARMOperand *OldMnemonic = ((ARMOperand*)Operands[0]);
2200          Operands.erase(Operands.begin());
2201          delete OldMnemonic;
2202          Operands.insert(Operands.begin(),
2203                          ARMOperand::CreateToken(Mnemonic, NameLoc));
2204          ARMOperand *CCOut = ((ARMOperand*)Operands[1]);
2205          Operands.erase(Operands.begin() + 1);
2206          delete CCOut;
2207        }
2208      }
2209    }
2210  }
2211  switch (MatchResult) {
2212  case Match_Success:
2213    Out.EmitInstruction(Inst);
2214    return false;
2215  case Match_MissingFeature:
2216    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2217    return true;
2218  case Match_InvalidOperand: {
2219    SMLoc ErrorLoc = IDLoc;
2220    if (ErrorInfo != ~0U) {
2221      if (ErrorInfo >= Operands.size())
2222        return Error(IDLoc, "too few operands for instruction");
2223
2224      ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc();
2225      if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
2226    }
2227
2228    return Error(ErrorLoc, "invalid operand for instruction");
2229  }
2230  case Match_MnemonicFail:
2231    return Error(IDLoc, "unrecognized instruction mnemonic");
2232  case Match_ConversionFail:
2233    return Error(IDLoc, "unable to convert operands to instruction");
2234  }
2235
2236  llvm_unreachable("Implement any new match types added!");
2237  return true;
2238}
2239
2240/// ParseDirective parses the arm specific directives
2241bool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
2242  StringRef IDVal = DirectiveID.getIdentifier();
2243  if (IDVal == ".word")
2244    return ParseDirectiveWord(4, DirectiveID.getLoc());
2245  else if (IDVal == ".thumb")
2246    return ParseDirectiveThumb(DirectiveID.getLoc());
2247  else if (IDVal == ".thumb_func")
2248    return ParseDirectiveThumbFunc(DirectiveID.getLoc());
2249  else if (IDVal == ".code")
2250    return ParseDirectiveCode(DirectiveID.getLoc());
2251  else if (IDVal == ".syntax")
2252    return ParseDirectiveSyntax(DirectiveID.getLoc());
2253  return true;
2254}
2255
2256/// ParseDirectiveWord
2257///  ::= .word [ expression (, expression)* ]
2258bool ARMAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
2259  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2260    for (;;) {
2261      const MCExpr *Value;
2262      if (getParser().ParseExpression(Value))
2263        return true;
2264
2265      getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/);
2266
2267      if (getLexer().is(AsmToken::EndOfStatement))
2268        break;
2269
2270      // FIXME: Improve diagnostic.
2271      if (getLexer().isNot(AsmToken::Comma))
2272        return Error(L, "unexpected token in directive");
2273      Parser.Lex();
2274    }
2275  }
2276
2277  Parser.Lex();
2278  return false;
2279}
2280
2281/// ParseDirectiveThumb
2282///  ::= .thumb
2283bool ARMAsmParser::ParseDirectiveThumb(SMLoc L) {
2284  if (getLexer().isNot(AsmToken::EndOfStatement))
2285    return Error(L, "unexpected token in directive");
2286  Parser.Lex();
2287
2288  // TODO: set thumb mode
2289  // TODO: tell the MC streamer the mode
2290  // getParser().getStreamer().Emit???();
2291  return false;
2292}
2293
2294/// ParseDirectiveThumbFunc
2295///  ::= .thumbfunc symbol_name
2296bool ARMAsmParser::ParseDirectiveThumbFunc(SMLoc L) {
2297  const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo();
2298  bool isMachO = MAI.hasSubsectionsViaSymbols();
2299  StringRef Name;
2300
2301  // Darwin asm has function name after .thumb_func direction
2302  // ELF doesn't
2303  if (isMachO) {
2304    const AsmToken &Tok = Parser.getTok();
2305    if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String))
2306      return Error(L, "unexpected token in .thumb_func directive");
2307    Name = Tok.getString();
2308    Parser.Lex(); // Consume the identifier token.
2309  }
2310
2311  if (getLexer().isNot(AsmToken::EndOfStatement))
2312    return Error(L, "unexpected token in directive");
2313  Parser.Lex();
2314
2315  // FIXME: assuming function name will be the line following .thumb_func
2316  if (!isMachO) {
2317    Name = Parser.getTok().getString();
2318  }
2319
2320  // Mark symbol as a thumb symbol.
2321  MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name);
2322  getParser().getStreamer().EmitThumbFunc(Func);
2323  return false;
2324}
2325
2326/// ParseDirectiveSyntax
2327///  ::= .syntax unified | divided
2328bool ARMAsmParser::ParseDirectiveSyntax(SMLoc L) {
2329  const AsmToken &Tok = Parser.getTok();
2330  if (Tok.isNot(AsmToken::Identifier))
2331    return Error(L, "unexpected token in .syntax directive");
2332  StringRef Mode = Tok.getString();
2333  if (Mode == "unified" || Mode == "UNIFIED")
2334    Parser.Lex();
2335  else if (Mode == "divided" || Mode == "DIVIDED")
2336    return Error(L, "'.syntax divided' arm asssembly not supported");
2337  else
2338    return Error(L, "unrecognized syntax mode in .syntax directive");
2339
2340  if (getLexer().isNot(AsmToken::EndOfStatement))
2341    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
2342  Parser.Lex();
2343
2344  // TODO tell the MC streamer the mode
2345  // getParser().getStreamer().Emit???();
2346  return false;
2347}
2348
2349/// ParseDirectiveCode
2350///  ::= .code 16 | 32
2351bool ARMAsmParser::ParseDirectiveCode(SMLoc L) {
2352  const AsmToken &Tok = Parser.getTok();
2353  if (Tok.isNot(AsmToken::Integer))
2354    return Error(L, "unexpected token in .code directive");
2355  int64_t Val = Parser.getTok().getIntVal();
2356  if (Val == 16)
2357    Parser.Lex();
2358  else if (Val == 32)
2359    Parser.Lex();
2360  else
2361    return Error(L, "invalid operand to .code directive");
2362
2363  if (getLexer().isNot(AsmToken::EndOfStatement))
2364    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
2365  Parser.Lex();
2366
2367  if (Val == 16) {
2368    if (!isThumb())
2369      SwitchMode();
2370    getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
2371  } else {
2372    if (isThumb())
2373      SwitchMode();
2374    getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
2375  }
2376
2377  return false;
2378}
2379
2380extern "C" void LLVMInitializeARMAsmLexer();
2381
2382/// Force static initialization.
2383extern "C" void LLVMInitializeARMAsmParser() {
2384  RegisterAsmParser<ARMAsmParser> X(TheARMTarget);
2385  RegisterAsmParser<ARMAsmParser> Y(TheThumbTarget);
2386  LLVMInitializeARMAsmLexer();
2387}
2388
2389#define GET_REGISTER_MATCHER
2390#define GET_MATCHER_IMPLEMENTATION
2391#include "ARMGenAsmMatcher.inc"
2392