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