b5f2e12e1c5d2a87a94b69c58174c6f67e532644
[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 "ARMSubtarget.h"
13 #include "llvm/MC/MCParser/MCAsmLexer.h"
14 #include "llvm/MC/MCParser/MCAsmParser.h"
15 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
16 #include "llvm/MC/MCContext.h"
17 #include "llvm/MC/MCStreamer.h"
18 #include "llvm/MC/MCExpr.h"
19 #include "llvm/MC/MCInst.h"
20 #include "llvm/Target/TargetRegistry.h"
21 #include "llvm/Target/TargetAsmParser.h"
22 #include "llvm/Support/SourceMgr.h"
23 #include "llvm/Support/raw_ostream.h"
24 #include "llvm/ADT/SmallVector.h"
25 #include "llvm/ADT/StringSwitch.h"
26 #include "llvm/ADT/Twine.h"
27 using namespace llvm;
28
29 // The shift types for register controlled shifts in arm memory addressing
30 enum ShiftType {
31   Lsl,
32   Lsr,
33   Asr,
34   Ror,
35   Rrx
36 };
37
38 namespace {
39
40 class ARMOperand;
41
42 class ARMAsmParser : public TargetAsmParser {
43   MCAsmParser &Parser;
44   TargetMachine &TM;
45
46   MCAsmParser &getParser() const { return Parser; }
47   MCAsmLexer &getLexer() const { return Parser.getLexer(); }
48
49   void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }
50   bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
51
52   int TryParseRegister();
53   ARMOperand *TryParseRegisterWithWriteBack();
54   ARMOperand *ParseRegisterList();
55   ARMOperand *ParseMemory();
56   ARMOperand *ParseOperand();
57
58   bool ParseMemoryOffsetReg(bool &Negative,
59                             bool &OffsetRegShifted,
60                             enum ShiftType &ShiftType,
61                             const MCExpr *&ShiftAmount,
62                             const MCExpr *&Offset,
63                             bool &OffsetIsReg,
64                             int &OffsetRegNum,
65                             SMLoc &E);
66   bool ParseShift(enum ShiftType &St, const MCExpr *&ShiftAmount, SMLoc &E);
67   bool ParseDirectiveWord(unsigned Size, SMLoc L);
68   bool ParseDirectiveThumb(SMLoc L);
69   bool ParseDirectiveThumbFunc(SMLoc L);
70   bool ParseDirectiveCode(SMLoc L);
71   bool ParseDirectiveSyntax(SMLoc L);
72
73   bool MatchAndEmitInstruction(SMLoc IDLoc,
74                                SmallVectorImpl<MCParsedAsmOperand*> &Operands,
75                                MCStreamer &Out);
76
77   /// @name Auto-generated Match Functions
78   /// {
79
80 #define GET_ASSEMBLER_HEADER
81 #include "ARMGenAsmMatcher.inc"
82
83   /// }
84
85 public:
86   ARMAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &_TM)
87     : TargetAsmParser(T), Parser(_Parser), TM(_TM) {
88       // Initialize the set of available features.
89       setAvailableFeatures(ComputeAvailableFeatures(
90           &TM.getSubtarget<ARMSubtarget>()));
91     }
92
93   virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc,
94                                 SmallVectorImpl<MCParsedAsmOperand*> &Operands);
95   virtual bool ParseDirective(AsmToken DirectiveID);
96 };
97 } // end anonymous namespace
98
99 namespace {
100
101 /// ARMOperand - Instances of this class represent a parsed ARM machine
102 /// instruction.
103 class ARMOperand : public MCParsedAsmOperand {
104   enum KindTy {
105     CondCode,
106     Immediate,
107     Memory,
108     Register,
109     RegisterList,
110     DPRRegisterList,
111     SPRRegisterList,
112     Token
113   } Kind;
114
115   SMLoc StartLoc, EndLoc;
116   SmallVector<unsigned, 8> Registers;
117
118   union {
119     struct {
120       ARMCC::CondCodes Val;
121     } CC;
122
123     struct {
124       const char *Data;
125       unsigned Length;
126     } Tok;
127
128     struct {
129       unsigned RegNum;
130       bool Writeback;
131     } Reg;
132
133     struct {
134       const MCExpr *Val;
135     } Imm;
136
137     // This is for all forms of ARM address expressions
138     struct {
139       unsigned BaseRegNum;
140       unsigned OffsetRegNum;         // used when OffsetIsReg is true
141       const MCExpr *Offset;          // used when OffsetIsReg is false
142       const MCExpr *ShiftAmount;     // used when OffsetRegShifted is true
143       enum ShiftType ShiftType;      // used when OffsetRegShifted is true
144       unsigned OffsetRegShifted : 1; // only used when OffsetIsReg is true
145       unsigned Preindexed : 1;
146       unsigned Postindexed : 1;
147       unsigned OffsetIsReg : 1;
148       unsigned Negative : 1;         // only used when OffsetIsReg is true
149       unsigned Writeback : 1;
150     } Mem;
151   };
152
153   ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
154 public:
155   ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() {
156     Kind = o.Kind;
157     StartLoc = o.StartLoc;
158     EndLoc = o.EndLoc;
159     switch (Kind) {
160     case CondCode:
161       CC = o.CC;
162       break;
163     case Token:
164       Tok = o.Tok;
165       break;
166     case Register:
167       Reg = o.Reg;
168       break;
169     case RegisterList:
170     case DPRRegisterList:
171     case SPRRegisterList:
172       Registers = o.Registers;
173       break;
174     case Immediate:
175       Imm = o.Imm;
176       break;
177     case Memory:
178       Mem = o.Mem;
179       break;
180     }
181   }
182
183   /// getStartLoc - Get the location of the first token of this operand.
184   SMLoc getStartLoc() const { return StartLoc; }
185   /// getEndLoc - Get the location of the last token of this operand.
186   SMLoc getEndLoc() const { return EndLoc; }
187
188   ARMCC::CondCodes getCondCode() const {
189     assert(Kind == CondCode && "Invalid access!");
190     return CC.Val;
191   }
192
193   StringRef getToken() const {
194     assert(Kind == Token && "Invalid access!");
195     return StringRef(Tok.Data, Tok.Length);
196   }
197
198   unsigned getReg() const {
199     assert(Kind == Register && "Invalid access!");
200     return Reg.RegNum;
201   }
202
203   const SmallVectorImpl<unsigned> &getRegList() const {
204     assert((Kind == RegisterList || Kind == DPRRegisterList ||
205             Kind == SPRRegisterList) && "Invalid access!");
206     return Registers;
207   }
208
209   const MCExpr *getImm() const {
210     assert(Kind == Immediate && "Invalid access!");
211     return Imm.Val;
212   }
213
214   bool isCondCode() const { return Kind == CondCode; }
215   bool isImm() const { return Kind == Immediate; }
216   bool isReg() const { return Kind == Register; }
217   bool isRegList() const { return Kind == RegisterList; }
218   bool isDPRRegList() const { return Kind == DPRRegisterList; }
219   bool isSPRRegList() const { return Kind == SPRRegisterList; }
220   bool isToken() const { return Kind == Token; }
221   bool isMemory() const { return Kind == Memory; }
222   bool isMemMode5() const {
223     if (!isMemory() || Mem.OffsetIsReg || Mem.OffsetRegShifted ||
224         Mem.Writeback || Mem.Negative)
225       return false;
226     // If there is an offset expression, make sure it's valid.
227     if (!Mem.Offset)
228       return true;
229     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Mem.Offset);
230     if (!CE)
231       return false;
232     // The offset must be a multiple of 4 in the range 0-1020.
233     int64_t Value = CE->getValue();
234     return ((Value & 0x3) == 0 && Value <= 1020 && Value >= -1020);
235   }
236
237   void addExpr(MCInst &Inst, const MCExpr *Expr) const {
238     // Add as immediates when possible.  Null MCExpr = 0.
239     if (Expr == 0)
240       Inst.addOperand(MCOperand::CreateImm(0));
241     else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
242       Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
243     else
244       Inst.addOperand(MCOperand::CreateExpr(Expr));
245   }
246
247   void addCondCodeOperands(MCInst &Inst, unsigned N) const {
248     assert(N == 2 && "Invalid number of operands!");
249     Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode())));
250     // FIXME: What belongs here?
251     Inst.addOperand(MCOperand::CreateReg(0));
252   }
253
254   void addRegOperands(MCInst &Inst, unsigned N) const {
255     assert(N == 1 && "Invalid number of operands!");
256     Inst.addOperand(MCOperand::CreateReg(getReg()));
257   }
258
259   void addRegListOperands(MCInst &Inst, unsigned N) const {
260     assert(N == 1 && "Invalid number of operands!");
261     const SmallVectorImpl<unsigned> &RegList = getRegList();
262     for (SmallVectorImpl<unsigned>::const_iterator
263            I = RegList.begin(), E = RegList.end(); I != E; ++I)
264       Inst.addOperand(MCOperand::CreateReg(*I));
265   }
266
267   void addDPRRegListOperands(MCInst &Inst, unsigned N) const {
268     addRegListOperands(Inst, N);
269   }
270
271   void addSPRRegListOperands(MCInst &Inst, unsigned N) const {
272     addRegListOperands(Inst, N);
273   }
274
275   void addImmOperands(MCInst &Inst, unsigned N) const {
276     assert(N == 1 && "Invalid number of operands!");
277     addExpr(Inst, getImm());
278   }
279
280   void addMemMode5Operands(MCInst &Inst, unsigned N) const {
281     assert(N == 2 && isMemMode5() && "Invalid number of operands!");
282
283     Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
284     assert(!Mem.OffsetIsReg && "Invalid mode 5 operand");
285
286     // FIXME: #-0 is encoded differently than #0. Does the parser preserve
287     // the difference?
288     if (Mem.Offset) {
289       const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Mem.Offset);
290       assert(CE && "Non-constant mode 5 offset operand!");
291
292       // The MCInst offset operand doesn't include the low two bits (like
293       // the instruction encoding).
294       int64_t Offset = CE->getValue() / 4;
295       if (Offset >= 0)
296         Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::add,
297                                                                Offset)));
298       else
299         Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::sub,
300                                                                -Offset)));
301     } else {
302       Inst.addOperand(MCOperand::CreateImm(0));
303     }
304   }
305
306   virtual void dump(raw_ostream &OS) const;
307
308   static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) {
309     ARMOperand *Op = new ARMOperand(CondCode);
310     Op->CC.Val = CC;
311     Op->StartLoc = S;
312     Op->EndLoc = S;
313     return Op;
314   }
315
316   static ARMOperand *CreateToken(StringRef Str, SMLoc S) {
317     ARMOperand *Op = new ARMOperand(Token);
318     Op->Tok.Data = Str.data();
319     Op->Tok.Length = Str.size();
320     Op->StartLoc = S;
321     Op->EndLoc = S;
322     return Op;
323   }
324
325   static ARMOperand *CreateReg(unsigned RegNum, bool Writeback, SMLoc S,
326                                SMLoc E) {
327     ARMOperand *Op = new ARMOperand(Register);
328     Op->Reg.RegNum = RegNum;
329     Op->Reg.Writeback = Writeback;
330     Op->StartLoc = S;
331     Op->EndLoc = E;
332     return Op;
333   }
334
335   static ARMOperand *
336   CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs,
337                 SMLoc StartLoc, SMLoc EndLoc) {
338     KindTy Kind = RegisterList;
339
340     if (ARM::DPRRegClass.contains(Regs.front().first))
341       Kind = DPRRegisterList;
342     else if (ARM::SPRRegClass.contains(Regs.front().first))
343       Kind = SPRRegisterList;
344
345     ARMOperand *Op = new ARMOperand(Kind);
346     for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator
347            I = Regs.begin(), E = Regs.end(); I != E; ++I)
348       Op->Registers.push_back(I->first);
349     std::sort(Op->Registers.begin(), Op->Registers.end());
350     Op->StartLoc = StartLoc;
351     Op->EndLoc = EndLoc;
352     return Op;
353   }
354
355   static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
356     ARMOperand *Op = new ARMOperand(Immediate);
357     Op->Imm.Val = Val;
358     Op->StartLoc = S;
359     Op->EndLoc = E;
360     return Op;
361   }
362
363   static ARMOperand *CreateMem(unsigned BaseRegNum, bool OffsetIsReg,
364                                const MCExpr *Offset, unsigned OffsetRegNum,
365                                bool OffsetRegShifted, enum ShiftType ShiftType,
366                                const MCExpr *ShiftAmount, bool Preindexed,
367                                bool Postindexed, bool Negative, bool Writeback,
368                                SMLoc S, SMLoc E) {
369     ARMOperand *Op = new ARMOperand(Memory);
370     Op->Mem.BaseRegNum = BaseRegNum;
371     Op->Mem.OffsetIsReg = OffsetIsReg;
372     Op->Mem.Offset = Offset;
373     Op->Mem.OffsetRegNum = OffsetRegNum;
374     Op->Mem.OffsetRegShifted = OffsetRegShifted;
375     Op->Mem.ShiftType = ShiftType;
376     Op->Mem.ShiftAmount = ShiftAmount;
377     Op->Mem.Preindexed = Preindexed;
378     Op->Mem.Postindexed = Postindexed;
379     Op->Mem.Negative = Negative;
380     Op->Mem.Writeback = Writeback;
381
382     Op->StartLoc = S;
383     Op->EndLoc = E;
384     return Op;
385   }
386 };
387
388 } // end anonymous namespace.
389
390 void ARMOperand::dump(raw_ostream &OS) const {
391   switch (Kind) {
392   case CondCode:
393     OS << ARMCondCodeToString(getCondCode());
394     break;
395   case Immediate:
396     getImm()->print(OS);
397     break;
398   case Memory:
399     OS << "<memory" << (!Mem.Writeback ? ">" : "!>");
400     break;
401   case Register:
402     OS << "<register " << getReg() << (!Reg.Writeback ? ">" : "!>");
403     break;
404   case RegisterList:
405   case DPRRegisterList:
406   case SPRRegisterList: {
407     OS << "<register_list ";
408
409     const SmallVectorImpl<unsigned> &RegList = getRegList();
410     for (SmallVectorImpl<unsigned>::const_iterator
411            I = RegList.begin(), E = RegList.end(); I != E; ) {
412       OS << *I;
413       if (++I < E) OS << ", ";
414     }
415
416     OS << ">";
417     break;
418   }
419   case Token:
420     OS << "'" << getToken() << "'";
421     break;
422   }
423 }
424
425 /// @name Auto-generated Match Functions
426 /// {
427
428 static unsigned MatchRegisterName(StringRef Name);
429
430 /// }
431
432 /// Try to parse a register name.  The token must be an Identifier when called,
433 /// and if it is a register name the token is eaten and the register number is
434 /// returned.  Otherwise return -1.
435 ///
436 int ARMAsmParser::TryParseRegister() {
437   const AsmToken &Tok = Parser.getTok();
438   assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
439
440   // FIXME: Validate register for the current architecture; we have to do
441   // validation later, so maybe there is no need for this here.
442   unsigned RegNum = MatchRegisterName(Tok.getString());
443   if (RegNum == 0)
444     return -1;
445   Parser.Lex(); // Eat identifier token.
446   return RegNum;
447 }
448
449
450 /// Try to parse a register name.  The token must be an Identifier when called,
451 /// and if it is a register name the token is eaten and the register number is
452 /// returned.  Otherwise return -1.
453 ///
454 /// TODO this is likely to change to allow different register types and or to
455 /// parse for a specific register type.
456 ARMOperand *ARMAsmParser::TryParseRegisterWithWriteBack() {
457   SMLoc S = Parser.getTok().getLoc();
458   int RegNo = TryParseRegister();
459   if (RegNo == -1)
460     return 0;
461
462   SMLoc E = Parser.getTok().getLoc();
463
464   bool Writeback = false;
465   const AsmToken &ExclaimTok = Parser.getTok();
466   if (ExclaimTok.is(AsmToken::Exclaim)) {
467     E = ExclaimTok.getLoc();
468     Writeback = true;
469     Parser.Lex(); // Eat exclaim token
470   }
471
472   return ARMOperand::CreateReg(RegNo, Writeback, S, E);
473 }
474
475 /// Parse a register list, return it if successful else return null.  The first
476 /// token must be a '{' when called.
477 ARMOperand *ARMAsmParser::ParseRegisterList() {
478   assert(Parser.getTok().is(AsmToken::LCurly) &&
479          "Token is not a Left Curly Brace");
480   SMLoc S = Parser.getTok().getLoc();
481
482   // Read the rest of the registers in the list.
483   unsigned PrevRegNum = 0;
484   SmallVector<std::pair<unsigned, SMLoc>, 32> Registers;
485
486   do {
487     bool IsRange = Parser.getTok().is(AsmToken::Minus);
488     Parser.Lex(); // Eat non-identifier token.
489
490     const AsmToken &RegTok = Parser.getTok();
491     SMLoc RegLoc = RegTok.getLoc();
492     if (RegTok.isNot(AsmToken::Identifier)) {
493       Error(RegLoc, "register expected");
494       return 0;
495     }
496
497     int RegNum = TryParseRegister();
498     if (RegNum == -1) {
499       Error(RegLoc, "register expected");
500       return 0;
501     }
502
503     if (IsRange) {
504       int Reg = PrevRegNum;
505       do {
506         ++Reg;
507         Registers.push_back(std::make_pair(Reg, RegLoc));
508       } while (Reg != RegNum);
509     } else {
510       Registers.push_back(std::make_pair(RegNum, RegLoc));
511     }
512
513     PrevRegNum = RegNum;
514   } while (Parser.getTok().is(AsmToken::Comma) ||
515            Parser.getTok().is(AsmToken::Minus));
516
517   // Process the right curly brace of the list.
518   const AsmToken &RCurlyTok = Parser.getTok();
519   if (RCurlyTok.isNot(AsmToken::RCurly)) {
520     Error(RCurlyTok.getLoc(), "'}' expected");
521     return 0;
522   }
523
524   SMLoc E = RCurlyTok.getLoc();
525   Parser.Lex(); // Eat right curly brace token.
526  
527   // Verify the register list.
528   SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator
529     RI = Registers.begin(), RE = Registers.end();
530
531   DenseMap<unsigned, bool> RegMap;
532   RegMap[RI->first] = true;
533
534   unsigned HighRegNum = RI->first;
535   bool EmittedWarning = false;
536
537   for (++RI; RI != RE; ++RI) {
538     const std::pair<unsigned, SMLoc> &RegInfo = *RI;
539     unsigned Reg = RegInfo.first;
540
541     if (RegMap[Reg]) {
542       Error(RegInfo.second, "register duplicated in register list");
543       return 0;
544     }
545
546     if (!EmittedWarning && Reg < HighRegNum)
547       Warning(RegInfo.second,
548               "register not in ascending order in register list");
549
550     RegMap[Reg] = true;
551     HighRegNum = std::max(Reg, HighRegNum);
552   }
553
554   return ARMOperand::CreateRegList(Registers, S, E);
555 }
556
557 /// Parse an ARM memory expression, return false if successful else return true
558 /// or an error.  The first token must be a '[' when called.
559 /// TODO Only preindexing and postindexing addressing are started, unindexed
560 /// with option, etc are still to do.
561 ARMOperand *ARMAsmParser::ParseMemory() {
562   SMLoc S, E;
563   assert(Parser.getTok().is(AsmToken::LBrac) &&
564          "Token is not a Left Bracket");
565   S = Parser.getTok().getLoc();
566   Parser.Lex(); // Eat left bracket token.
567
568   const AsmToken &BaseRegTok = Parser.getTok();
569   if (BaseRegTok.isNot(AsmToken::Identifier)) {
570     Error(BaseRegTok.getLoc(), "register expected");
571     return 0;
572   }
573   int BaseRegNum = TryParseRegister();
574   if (BaseRegNum == -1) {
575     Error(BaseRegTok.getLoc(), "register expected");
576     return 0;
577   }
578
579   bool Preindexed = false;
580   bool Postindexed = false;
581   bool OffsetIsReg = false;
582   bool Negative = false;
583   bool Writeback = false;
584
585   // First look for preindexed address forms, that is after the "[Rn" we now
586   // have to see if the next token is a comma.
587   const AsmToken &Tok = Parser.getTok();
588   if (Tok.is(AsmToken::Comma)) {
589     Preindexed = true;
590     Parser.Lex(); // Eat comma token.
591     int OffsetRegNum;
592     bool OffsetRegShifted;
593     enum ShiftType ShiftType;
594     const MCExpr *ShiftAmount;
595     const MCExpr *Offset;
596     if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, ShiftAmount,
597                              Offset, OffsetIsReg, OffsetRegNum, E))
598       return 0;
599     const AsmToken &RBracTok = Parser.getTok();
600     if (RBracTok.isNot(AsmToken::RBrac)) {
601       Error(RBracTok.getLoc(), "']' expected");
602       return 0;
603     }
604     E = RBracTok.getLoc();
605     Parser.Lex(); // Eat right bracket token.
606
607     const AsmToken &ExclaimTok = Parser.getTok();
608     if (ExclaimTok.is(AsmToken::Exclaim)) {
609       E = ExclaimTok.getLoc();
610       Writeback = true;
611       Parser.Lex(); // Eat exclaim token
612     }
613     return ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset, OffsetRegNum,
614                                  OffsetRegShifted, ShiftType, ShiftAmount,
615                                  Preindexed, Postindexed, Negative, Writeback,
616                                  S, E);
617   }
618   // The "[Rn" we have so far was not followed by a comma.
619   else if (Tok.is(AsmToken::RBrac)) {
620     // If there's anything other than the right brace, this is a post indexing
621     // addressing form.
622     E = Tok.getLoc();
623     Parser.Lex(); // Eat right bracket token.
624
625     int OffsetRegNum = 0;
626     bool OffsetRegShifted = false;
627     enum ShiftType ShiftType;
628     const MCExpr *ShiftAmount;
629     const MCExpr *Offset = 0;
630
631     const AsmToken &NextTok = Parser.getTok();
632     if (NextTok.isNot(AsmToken::EndOfStatement)) {
633       Postindexed = true;
634       Writeback = true;
635       if (NextTok.isNot(AsmToken::Comma)) {
636         Error(NextTok.getLoc(), "',' expected");
637         return 0;
638       }
639       Parser.Lex(); // Eat comma token.
640       if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType,
641                                ShiftAmount, Offset, OffsetIsReg, OffsetRegNum,
642                                E))
643         return 0;
644     }
645
646     return ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset, OffsetRegNum,
647                                  OffsetRegShifted, ShiftType, ShiftAmount,
648                                  Preindexed, Postindexed, Negative, Writeback,
649                                  S, E);
650   }
651
652   return 0;
653 }
654
655 /// Parse the offset of a memory operand after we have seen "[Rn," or "[Rn],"
656 /// we will parse the following (were +/- means that a plus or minus is
657 /// optional):
658 ///   +/-Rm
659 ///   +/-Rm, shift
660 ///   #offset
661 /// we return false on success or an error otherwise.
662 bool ARMAsmParser::ParseMemoryOffsetReg(bool &Negative,
663                                         bool &OffsetRegShifted,
664                                         enum ShiftType &ShiftType,
665                                         const MCExpr *&ShiftAmount,
666                                         const MCExpr *&Offset,
667                                         bool &OffsetIsReg,
668                                         int &OffsetRegNum,
669                                         SMLoc &E) {
670   Negative = false;
671   OffsetRegShifted = false;
672   OffsetIsReg = false;
673   OffsetRegNum = -1;
674   const AsmToken &NextTok = Parser.getTok();
675   E = NextTok.getLoc();
676   if (NextTok.is(AsmToken::Plus))
677     Parser.Lex(); // Eat plus token.
678   else if (NextTok.is(AsmToken::Minus)) {
679     Negative = true;
680     Parser.Lex(); // Eat minus token
681   }
682   // See if there is a register following the "[Rn," or "[Rn]," we have so far.
683   const AsmToken &OffsetRegTok = Parser.getTok();
684   if (OffsetRegTok.is(AsmToken::Identifier)) {
685     SMLoc CurLoc = OffsetRegTok.getLoc();
686     OffsetRegNum = TryParseRegister();
687     if (OffsetRegNum != -1) {
688       OffsetIsReg = true;
689       E = CurLoc;
690     }
691   }
692
693   // If we parsed a register as the offset then there can be a shift after that.
694   if (OffsetRegNum != -1) {
695     // Look for a comma then a shift
696     const AsmToken &Tok = Parser.getTok();
697     if (Tok.is(AsmToken::Comma)) {
698       Parser.Lex(); // Eat comma token.
699
700       const AsmToken &Tok = Parser.getTok();
701       if (ParseShift(ShiftType, ShiftAmount, E))
702         return Error(Tok.getLoc(), "shift expected");
703       OffsetRegShifted = true;
704     }
705   }
706   else { // the "[Rn," or "[Rn,]" we have so far was not followed by "Rm"
707     // Look for #offset following the "[Rn," or "[Rn],"
708     const AsmToken &HashTok = Parser.getTok();
709     if (HashTok.isNot(AsmToken::Hash))
710       return Error(HashTok.getLoc(), "'#' expected");
711
712     Parser.Lex(); // Eat hash token.
713
714     if (getParser().ParseExpression(Offset))
715      return true;
716     E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
717   }
718   return false;
719 }
720
721 /// ParseShift as one of these two:
722 ///   ( lsl | lsr | asr | ror ) , # shift_amount
723 ///   rrx
724 /// and returns true if it parses a shift otherwise it returns false.
725 bool ARMAsmParser::ParseShift(ShiftType &St, const MCExpr *&ShiftAmount,
726                               SMLoc &E) {
727   const AsmToken &Tok = Parser.getTok();
728   if (Tok.isNot(AsmToken::Identifier))
729     return true;
730   StringRef ShiftName = Tok.getString();
731   if (ShiftName == "lsl" || ShiftName == "LSL")
732     St = Lsl;
733   else if (ShiftName == "lsr" || ShiftName == "LSR")
734     St = Lsr;
735   else if (ShiftName == "asr" || ShiftName == "ASR")
736     St = Asr;
737   else if (ShiftName == "ror" || ShiftName == "ROR")
738     St = Ror;
739   else if (ShiftName == "rrx" || ShiftName == "RRX")
740     St = Rrx;
741   else
742     return true;
743   Parser.Lex(); // Eat shift type token.
744
745   // Rrx stands alone.
746   if (St == Rrx)
747     return false;
748
749   // Otherwise, there must be a '#' and a shift amount.
750   const AsmToken &HashTok = Parser.getTok();
751   if (HashTok.isNot(AsmToken::Hash))
752     return Error(HashTok.getLoc(), "'#' expected");
753   Parser.Lex(); // Eat hash token.
754
755   if (getParser().ParseExpression(ShiftAmount))
756     return true;
757
758   return false;
759 }
760
761 /// Parse a arm instruction operand.  For now this parses the operand regardless
762 /// of the mnemonic.
763 ARMOperand *ARMAsmParser::ParseOperand() {
764   SMLoc S, E;
765   switch (getLexer().getKind()) {
766   default:
767     Error(Parser.getTok().getLoc(), "unexpected token in operand");
768     return 0;
769   case AsmToken::Identifier:
770     if (ARMOperand *Op = TryParseRegisterWithWriteBack())
771       return Op;
772
773     // This was not a register so parse other operands that start with an
774     // identifier (like labels) as expressions and create them as immediates.
775     const MCExpr *IdVal;
776     S = Parser.getTok().getLoc();
777     if (getParser().ParseExpression(IdVal))
778       return 0;
779     E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
780     return ARMOperand::CreateImm(IdVal, S, E);
781   case AsmToken::LBrac:
782     return ParseMemory();
783   case AsmToken::LCurly:
784     return ParseRegisterList();
785   case AsmToken::Hash:
786     // #42 -> immediate.
787     // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate
788     S = Parser.getTok().getLoc();
789     Parser.Lex();
790     const MCExpr *ImmVal;
791     if (getParser().ParseExpression(ImmVal))
792       return 0;
793     E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
794     return ARMOperand::CreateImm(ImmVal, S, E);
795   }
796 }
797
798 /// Parse an arm instruction mnemonic followed by its operands.
799 bool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc,
800                                SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
801   // Create the leading tokens for the mnemonic, split by '.' characters.
802   size_t Start = 0, Next = Name.find('.');
803   StringRef Head = Name.slice(Start, Next);
804
805   // Determine the predicate, if any.
806   //
807   // FIXME: We need a way to check whether a prefix supports predication,
808   // otherwise we will end up with an ambiguity for instructions that happen to
809   // end with a predicate name.
810   // FIXME: Likewise, some arithmetic instructions have an 's' prefix which
811   // indicates to update the condition codes. Those instructions have an
812   // additional immediate operand which encodes the prefix as reg0 or CPSR.
813   // Just checking for a suffix of 's' definitely creates ambiguities; e.g,
814   // the SMMLS instruction.
815   unsigned CC = StringSwitch<unsigned>(Head.substr(Head.size()-2))
816     .Case("eq", ARMCC::EQ)
817     .Case("ne", ARMCC::NE)
818     .Case("hs", ARMCC::HS)
819     .Case("lo", ARMCC::LO)
820     .Case("mi", ARMCC::MI)
821     .Case("pl", ARMCC::PL)
822     .Case("vs", ARMCC::VS)
823     .Case("vc", ARMCC::VC)
824     .Case("hi", ARMCC::HI)
825     .Case("ls", ARMCC::LS)
826     .Case("ge", ARMCC::GE)
827     .Case("lt", ARMCC::LT)
828     .Case("gt", ARMCC::GT)
829     .Case("le", ARMCC::LE)
830     .Case("al", ARMCC::AL)
831     .Default(~0U);
832
833   if (CC == ~0U ||
834       (CC == ARMCC::LS && (Head == "vmls" || Head == "vnmls"))) {
835     CC = ARMCC::AL;
836   } else {
837     Head = Head.slice(0, Head.size() - 2);
838   }
839
840   Operands.push_back(ARMOperand::CreateToken(Head, NameLoc));
841   // FIXME: Should only add this operand for predicated instructions
842   Operands.push_back(ARMOperand::CreateCondCode(ARMCC::CondCodes(CC), NameLoc));
843
844   // Add the remaining tokens in the mnemonic.
845   while (Next != StringRef::npos) {
846     Start = Next;
847     Next = Name.find('.', Start + 1);
848     Head = Name.slice(Start, Next);
849
850     Operands.push_back(ARMOperand::CreateToken(Head, NameLoc));
851   }
852
853   // Read the remaining operands.
854   if (getLexer().isNot(AsmToken::EndOfStatement)) {
855     // Read the first operand.
856     if (ARMOperand *Op = ParseOperand())
857       Operands.push_back(Op);
858     else {
859       Parser.EatToEndOfStatement();
860       return true;
861     }
862
863     while (getLexer().is(AsmToken::Comma)) {
864       Parser.Lex();  // Eat the comma.
865
866       // Parse and remember the operand.
867       if (ARMOperand *Op = ParseOperand())
868         Operands.push_back(Op);
869       else {
870         Parser.EatToEndOfStatement();
871         return true;
872       }
873     }
874   }
875
876   if (getLexer().isNot(AsmToken::EndOfStatement)) {
877     Parser.EatToEndOfStatement();
878     return TokError("unexpected token in argument list");
879   }
880
881   Parser.Lex(); // Consume the EndOfStatement
882   return false;
883 }
884
885 bool ARMAsmParser::
886 MatchAndEmitInstruction(SMLoc IDLoc,
887                         SmallVectorImpl<MCParsedAsmOperand*> &Operands,
888                         MCStreamer &Out) {
889   MCInst Inst;
890   unsigned ErrorInfo;
891   switch (MatchInstructionImpl(Operands, Inst, ErrorInfo)) {
892   case Match_Success:
893     Out.EmitInstruction(Inst);
894     return false;
895   case Match_MissingFeature:
896     Error(IDLoc, "instruction requires a CPU feature not currently enabled");
897     return true;
898   case Match_InvalidOperand: {
899     SMLoc ErrorLoc = IDLoc;
900     if (ErrorInfo != ~0U) {
901       if (ErrorInfo >= Operands.size())
902         return Error(IDLoc, "too few operands for instruction");
903
904       ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc();
905       if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
906     }
907
908     return Error(ErrorLoc, "invalid operand for instruction");
909   }
910   case Match_MnemonicFail:
911     return Error(IDLoc, "unrecognized instruction mnemonic");
912   }
913
914   llvm_unreachable("Implement any new match types added!");
915   return true;
916 }
917
918 /// ParseDirective parses the arm specific directives
919 bool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
920   StringRef IDVal = DirectiveID.getIdentifier();
921   if (IDVal == ".word")
922     return ParseDirectiveWord(4, DirectiveID.getLoc());
923   else if (IDVal == ".thumb")
924     return ParseDirectiveThumb(DirectiveID.getLoc());
925   else if (IDVal == ".thumb_func")
926     return ParseDirectiveThumbFunc(DirectiveID.getLoc());
927   else if (IDVal == ".code")
928     return ParseDirectiveCode(DirectiveID.getLoc());
929   else if (IDVal == ".syntax")
930     return ParseDirectiveSyntax(DirectiveID.getLoc());
931   return true;
932 }
933
934 /// ParseDirectiveWord
935 ///  ::= .word [ expression (, expression)* ]
936 bool ARMAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
937   if (getLexer().isNot(AsmToken::EndOfStatement)) {
938     for (;;) {
939       const MCExpr *Value;
940       if (getParser().ParseExpression(Value))
941         return true;
942
943       getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/);
944
945       if (getLexer().is(AsmToken::EndOfStatement))
946         break;
947
948       // FIXME: Improve diagnostic.
949       if (getLexer().isNot(AsmToken::Comma))
950         return Error(L, "unexpected token in directive");
951       Parser.Lex();
952     }
953   }
954
955   Parser.Lex();
956   return false;
957 }
958
959 /// ParseDirectiveThumb
960 ///  ::= .thumb
961 bool ARMAsmParser::ParseDirectiveThumb(SMLoc L) {
962   if (getLexer().isNot(AsmToken::EndOfStatement))
963     return Error(L, "unexpected token in directive");
964   Parser.Lex();
965
966   // TODO: set thumb mode
967   // TODO: tell the MC streamer the mode
968   // getParser().getStreamer().Emit???();
969   return false;
970 }
971
972 /// ParseDirectiveThumbFunc
973 ///  ::= .thumbfunc symbol_name
974 bool ARMAsmParser::ParseDirectiveThumbFunc(SMLoc L) {
975   const AsmToken &Tok = Parser.getTok();
976   if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String))
977     return Error(L, "unexpected token in .thumb_func directive");
978   StringRef Name = Tok.getString();
979   Parser.Lex(); // Consume the identifier token.
980   if (getLexer().isNot(AsmToken::EndOfStatement))
981     return Error(L, "unexpected token in directive");
982   Parser.Lex();
983
984   // Mark symbol as a thumb symbol.
985   MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name);
986   getParser().getStreamer().EmitThumbFunc(Func);
987   return false;
988 }
989
990 /// ParseDirectiveSyntax
991 ///  ::= .syntax unified | divided
992 bool ARMAsmParser::ParseDirectiveSyntax(SMLoc L) {
993   const AsmToken &Tok = Parser.getTok();
994   if (Tok.isNot(AsmToken::Identifier))
995     return Error(L, "unexpected token in .syntax directive");
996   StringRef Mode = Tok.getString();
997   if (Mode == "unified" || Mode == "UNIFIED")
998     Parser.Lex();
999   else if (Mode == "divided" || Mode == "DIVIDED")
1000     Parser.Lex();
1001   else
1002     return Error(L, "unrecognized syntax mode in .syntax directive");
1003
1004   if (getLexer().isNot(AsmToken::EndOfStatement))
1005     return Error(Parser.getTok().getLoc(), "unexpected token in directive");
1006   Parser.Lex();
1007
1008   // TODO tell the MC streamer the mode
1009   // getParser().getStreamer().Emit???();
1010   return false;
1011 }
1012
1013 /// ParseDirectiveCode
1014 ///  ::= .code 16 | 32
1015 bool ARMAsmParser::ParseDirectiveCode(SMLoc L) {
1016   const AsmToken &Tok = Parser.getTok();
1017   if (Tok.isNot(AsmToken::Integer))
1018     return Error(L, "unexpected token in .code directive");
1019   int64_t Val = Parser.getTok().getIntVal();
1020   if (Val == 16)
1021     Parser.Lex();
1022   else if (Val == 32)
1023     Parser.Lex();
1024   else
1025     return Error(L, "invalid operand to .code directive");
1026
1027   if (getLexer().isNot(AsmToken::EndOfStatement))
1028     return Error(Parser.getTok().getLoc(), "unexpected token in directive");
1029   Parser.Lex();
1030
1031   if (Val == 16)
1032     getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
1033   else
1034     getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
1035
1036   return false;
1037 }
1038
1039 extern "C" void LLVMInitializeARMAsmLexer();
1040
1041 /// Force static initialization.
1042 extern "C" void LLVMInitializeARMAsmParser() {
1043   RegisterAsmParser<ARMAsmParser> X(TheARMTarget);
1044   RegisterAsmParser<ARMAsmParser> Y(TheThumbTarget);
1045   LLVMInitializeARMAsmLexer();
1046 }
1047
1048 #define GET_REGISTER_MATCHER
1049 #define GET_MATCHER_IMPLEMENTATION
1050 #include "ARMGenAsmMatcher.inc"