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