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