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