]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - contrib/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
Copy head to stable/9 as part of 9.0-RELEASE release cycle.
[FreeBSD/stable/9.git] / contrib / llvm / lib / Target / ARM / AsmParser / ARMAsmParser.cpp
1 //===-- ARMAsmParser.cpp - Parse ARM assembly to MCInst instructions ------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "ARM.h"
11 #include "ARMAddressingModes.h"
12 #include "ARMMCExpr.h"
13 #include "ARMBaseRegisterInfo.h"
14 #include "ARMSubtarget.h"
15 #include "llvm/MC/MCParser/MCAsmLexer.h"
16 #include "llvm/MC/MCParser/MCAsmParser.h"
17 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
18 #include "llvm/MC/MCAsmInfo.h"
19 #include "llvm/MC/MCContext.h"
20 #include "llvm/MC/MCStreamer.h"
21 #include "llvm/MC/MCExpr.h"
22 #include "llvm/MC/MCInst.h"
23 #include "llvm/MC/MCSubtargetInfo.h"
24 #include "llvm/Target/TargetRegistry.h"
25 #include "llvm/Target/TargetAsmParser.h"
26 #include "llvm/Support/SourceMgr.h"
27 #include "llvm/Support/raw_ostream.h"
28 #include "llvm/ADT/OwningPtr.h"
29 #include "llvm/ADT/SmallVector.h"
30 #include "llvm/ADT/StringExtras.h"
31 #include "llvm/ADT/StringSwitch.h"
32 #include "llvm/ADT/Twine.h"
33
34 using namespace llvm;
35
36 namespace {
37
38 class ARMOperand;
39
40 class 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
130 public:
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
145 namespace {
146
147 /// ARMOperand - Instances of this class represent a parsed ARM machine
148 /// instruction.
149 class 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) {}
237 public:
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
923 void 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
1018 static unsigned MatchRegisterName(StringRef Name);
1019
1020 /// }
1021
1022 bool 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 ///
1033 int 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).
1061 int 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.
1150 bool ARMAsmParser::
1151 TryParseRegisterWithWriteBack(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", ...
1172 static 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.
1215 ARMAsmParser::OperandMatchResultTy ARMAsmParser::
1216 tryParseCoprocNumOperand(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.
1233 ARMAsmParser::OperandMatchResultTy ARMAsmParser::
1234 tryParseCoprocRegOperand(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.
1250 bool ARMAsmParser::
1251 ParseRegisterList(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.
1333 ARMAsmParser::OperandMatchResultTy ARMAsmParser::
1334 tryParseMemBarrierOptOperand(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.
1364 ARMAsmParser::OperandMatchResultTy ARMAsmParser::
1365 tryParseProcIFlagsOperand(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.
1393 ARMAsmParser::OperandMatchResultTy ARMAsmParser::
1394 tryParseMSRMaskOperand(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.
1459 ARMAsmParser::OperandMatchResultTy ARMAsmParser::
1460 tryParseMemMode2Operand(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.
1470 ARMAsmParser::OperandMatchResultTy ARMAsmParser::
1471 tryParseMemMode3Operand(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.
1483 bool ARMAsmParser::
1484 CvtLdWriteBackRegAddrMode2(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.
1499 bool ARMAsmParser::
1500 CvtStWriteBackRegAddrMode2(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.
1513 bool ARMAsmParser::
1514 CvtLdWriteBackRegAddrMode3(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.
1529 bool ARMAsmParser::
1530 CvtStWriteBackRegAddrMode3(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.
1545 bool ARMAsmParser::
1546 ParseMemory(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.
1669 bool 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.
1732 bool 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.
1770 bool 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:.
1851 bool 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
1882 const MCExpr *
1883 ARMAsmParser::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.
1927 static 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.
2014 void ARMAsmParser::
2015 GetMnemonicAcceptInfo(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.
2049 bool 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
2151 bool ARMAsmParser::
2152 MatchAndEmitInstruction(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
2240 bool 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)* ]
2257 bool 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
2282 bool 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
2295 bool 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
2327 bool 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
2350 bool 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
2379 extern "C" void LLVMInitializeARMAsmLexer();
2380
2381 /// Force static initialization.
2382 extern "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"