Added the TargetAsmLexer implementation for AT&T syntax.
[oota-llvm.git] / lib / Target / X86 / AsmParser / X86AsmLexer.cpp
1 //===-- X86AsmLexer.cpp - Tokenize X86 assembly to AsmTokens --------------===//
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 "llvm/ADT/SmallVector.h"
11 #include "llvm/Target/TargetAsmLexer.h"
12 #include "llvm/Target/TargetRegistry.h"
13 #include "llvm/MC/MCAsmInfo.h"
14 #include "llvm/MC/MCParser/MCAsmLexer.h"
15 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
16 #include "X86.h"
17
18 using namespace llvm;
19
20 namespace {
21   
22 class X86AsmLexer : public TargetAsmLexer {
23   const MCAsmInfo &AsmInfo;
24   MCAsmLexer *Lexer;
25   
26   bool tentativeIsValid;
27   AsmToken tentativeToken;
28   
29   const AsmToken &lexTentative() {
30     tentativeToken = Lexer->Lex();
31     tentativeIsValid = true;
32     return tentativeToken;
33   }
34   
35   const AsmToken &lexDefinite() {
36     if(tentativeIsValid) {
37       tentativeIsValid = false;
38       return tentativeToken;
39     }
40     else {
41       return Lexer->Lex();
42     }
43   }
44   
45   AsmToken LexTokenATT();
46   AsmToken LexTokenIntel();
47 protected:
48   AsmToken LexToken() {
49     if (!Lexer) {
50       SetError(SMLoc(), "No MCAsmLexer installed");
51       return AsmToken(AsmToken::Error, "", 0);
52     }
53     
54     switch (AsmInfo.getAssemblerDialect()) {
55     default:
56       SetError(SMLoc(), "Unhandled dialect");
57       return AsmToken(AsmToken::Error, "", 0);
58     case 0:
59       return LexTokenATT();
60     case 1:
61       return LexTokenIntel();
62     }
63   }
64 public:
65   X86AsmLexer(const Target &T, const MCAsmInfo &MAI)
66     : TargetAsmLexer(T), AsmInfo(MAI), Lexer(NULL), tentativeIsValid(false) {
67   }
68   
69   void InstallLexer(MCAsmLexer &L) {
70     Lexer = &L;
71   }
72 };
73
74 }
75
76 static unsigned MatchRegisterName(const StringRef &Name);
77
78 AsmToken X86AsmLexer::LexTokenATT() {
79   const AsmToken &lexedToken = lexDefinite();
80   
81   switch (lexedToken.getKind()) {
82   default:
83     return AsmToken(lexedToken);
84   case AsmToken::Error:
85     SetError(Lexer->getErrLoc(), Lexer->getErr());
86     return AsmToken(lexedToken);
87   case AsmToken::Percent:
88   {
89     const AsmToken &nextToken = lexTentative();
90     if (nextToken.getKind() == AsmToken::Identifier) {
91       unsigned regID = MatchRegisterName(nextToken.getString());
92       
93       if (regID) {
94         lexDefinite();
95         
96         StringRef regStr(lexedToken.getString().data(),
97                          lexedToken.getString().size() + 
98                          nextToken.getString().size());
99         
100         return AsmToken(AsmToken::Register, 
101                         regStr, 
102                         static_cast<int64_t>(regID));
103       }
104       else {
105         return AsmToken(lexedToken);
106       }
107     }
108     else {
109       return AsmToken(lexedToken);
110     }
111   }    
112   }
113 }
114
115 AsmToken X86AsmLexer::LexTokenIntel() {
116   return AsmToken(AsmToken::Error, "", 0);
117 }
118
119 extern "C" void LLVMInitializeX86AsmLexer() {
120   RegisterAsmLexer<X86AsmLexer> X(TheX86_32Target);
121   RegisterAsmLexer<X86AsmLexer> Y(TheX86_64Target);
122 }
123
124 #define REGISTERS_ONLY
125 #include "../X86GenAsmMatcher.inc"
126 #undef REGISTERS_ONLY