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