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