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