get a definition of strull on windows, thanks to Howard Su.
[oota-llvm.git] / tools / llvm-mc / AsmParser.cpp
1 //===- AsmParser.cpp - Parser for Assembly Files --------------------------===//
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 // This class implements the parser for assembly files.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "AsmParser.h"
15 #include "llvm/Support/SourceMgr.h"
16 #include "llvm/Support/raw_ostream.h"
17 using namespace llvm;
18
19 bool AsmParser::Error(SMLoc L, const char *Msg) {
20   Lexer.PrintMessage(L, Msg);
21   return true;
22 }
23
24 bool AsmParser::TokError(const char *Msg) {
25   Lexer.PrintMessage(Lexer.getLoc(), Msg);
26   return true;
27 }
28
29 bool AsmParser::Run() {
30   // Prime the lexer.
31   Lexer.Lex();
32   
33   while (Lexer.isNot(asmtok::Eof))
34     if (ParseStatement())
35       return true;
36   
37   return false;
38 }
39
40 /// EatToEndOfStatement - Throw away the rest of the line for testing purposes.
41 void AsmParser::EatToEndOfStatement() {
42   while (Lexer.isNot(asmtok::EndOfStatement) &&
43          Lexer.isNot(asmtok::Eof))
44     Lexer.Lex();
45   
46   // Eat EOL.
47   if (Lexer.is(asmtok::EndOfStatement))
48     Lexer.Lex();
49 }
50
51
52 struct AsmParser::X86Operand {
53   enum {
54     Register,
55     Immediate,
56     Memory
57   } Kind;
58   
59   union {
60     struct {
61       unsigned RegNo;
62     } Reg;
63
64     struct {
65       // FIXME: Should be a general expression.
66       int64_t Val;
67     } Imm;
68     
69     struct {
70       unsigned SegReg;
71       int64_t Disp;     // FIXME: Should be a general expression.
72       unsigned BaseReg;
73       unsigned Scale;
74       unsigned ScaleReg;
75     } Mem;
76   };
77   
78   static X86Operand CreateReg(unsigned RegNo) {
79     X86Operand Res;
80     Res.Kind = Register;
81     Res.Reg.RegNo = RegNo;
82     return Res;
83   }
84   static X86Operand CreateImm(int64_t Val) {
85     X86Operand Res;
86     Res.Kind = Immediate;
87     Res.Imm.Val = Val;
88     return Res;
89   }
90   static X86Operand CreateMem(unsigned SegReg, int64_t Disp, unsigned BaseReg,
91                               unsigned Scale, unsigned ScaleReg) {
92     X86Operand Res;
93     Res.Kind = Memory;
94     Res.Mem.SegReg   = SegReg;
95     Res.Mem.Disp     = Disp;
96     Res.Mem.BaseReg  = BaseReg;
97     Res.Mem.Scale    = Scale;
98     Res.Mem.ScaleReg = ScaleReg;
99     return Res;
100   }
101 };
102
103 bool AsmParser::ParseX86Operand(X86Operand &Op) {
104   switch (Lexer.getKind()) {
105   default:
106     return ParseX86MemOperand(Op);
107   case asmtok::Register:
108     // FIXME: Decode reg #.
109     // FIXME: if a segment register, this could either be just the seg reg, or
110     // the start of a memory operand.
111     Op = X86Operand::CreateReg(123);
112     Lexer.Lex(); // Eat register.
113     return false;
114   case asmtok::Dollar: {
115     // $42 -> immediate.
116     Lexer.Lex();
117     int64_t Val;
118     if (ParseExpression(Val))
119       return TokError("expected integer constant");
120     Op = X86Operand::CreateReg(Val);
121     return false;
122   case asmtok::Star:
123     Lexer.Lex(); // Eat the star.
124     
125     if (Lexer.is(asmtok::Register)) {
126       Op = X86Operand::CreateReg(123);
127       Lexer.Lex(); // Eat register.
128     } else if (ParseX86MemOperand(Op))
129       return true;
130
131     // FIXME: Note that these are 'dereferenced' so that clients know the '*' is
132     // there.
133     return false;
134   }
135   }
136 }
137
138 /// ParseX86MemOperand: segment: disp(basereg, indexreg, scale)
139 bool AsmParser::ParseX86MemOperand(X86Operand &Op) {
140   // FIXME: If SegReg ':'  (e.g. %gs:), eat and remember.
141   unsigned SegReg = 0;
142   
143   
144   // We have to disambiguate a parenthesized expression "(4+5)" from the start
145   // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)".  The
146   // only way to do this without lookahead is to eat the ( and see what is after
147   // it.
148   int64_t Disp = 0;
149   if (Lexer.isNot(asmtok::LParen)) {
150     if (ParseExpression(Disp)) return true;
151     
152     // After parsing the base expression we could either have a parenthesized
153     // memory address or not.  If not, return now.  If so, eat the (.
154     if (Lexer.isNot(asmtok::LParen)) {
155       Op = X86Operand::CreateMem(SegReg, Disp, 0, 0, 0);
156       return false;
157     }
158     
159     // Eat the '('.
160     Lexer.Lex();
161   } else {
162     // Okay, we have a '('.  We don't know if this is an expression or not, but
163     // so we have to eat the ( to see beyond it.
164     Lexer.Lex(); // Eat the '('.
165     
166     if (Lexer.is(asmtok::Register) || Lexer.is(asmtok::Comma)) {
167       // Nothing to do here, fall into the code below with the '(' part of the
168       // memory operand consumed.
169     } else {
170       // It must be an parenthesized expression, parse it now.
171       if (ParseParenExpr(Disp)) return true;
172       
173       // After parsing the base expression we could either have a parenthesized
174       // memory address or not.  If not, return now.  If so, eat the (.
175       if (Lexer.isNot(asmtok::LParen)) {
176         Op = X86Operand::CreateMem(SegReg, Disp, 0, 0, 0);
177         return false;
178       }
179       
180       // Eat the '('.
181       Lexer.Lex();
182     }
183   }
184   
185   // If we reached here, then we just ate the ( of the memory operand.  Process
186   // the rest of the memory operand.
187   unsigned BaseReg = 0, ScaleReg = 0, Scale = 0;
188   
189   if (Lexer.is(asmtok::Register)) {
190     BaseReg = 123; // FIXME: decode reg #
191     Lexer.Lex();  // eat the register.
192   }
193   
194   if (Lexer.is(asmtok::Comma)) {
195     Lexer.Lex(); // eat the comma.
196     
197     if (Lexer.is(asmtok::Register)) {
198       ScaleReg = 123; // FIXME: decode reg #
199       Lexer.Lex();  // eat the register.
200       Scale = 1;      // If not specified, the scale defaults to 1.
201     }
202     
203     if (Lexer.is(asmtok::Comma)) {
204       Lexer.Lex(); // eat the comma.
205
206       // If present, get and validate scale amount.
207       if (Lexer.is(asmtok::IntVal)) {
208         int64_t ScaleVal = Lexer.getCurIntVal();
209         if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8)
210           return TokError("scale factor in address must be 1, 2, 4 or 8");
211         Lexer.Lex();  // eat the scale.
212         Scale = (unsigned)ScaleVal;
213       }
214     }
215   }
216   
217   // Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
218   if (Lexer.isNot(asmtok::RParen))
219     return TokError("unexpected token in memory operand");
220   Lexer.Lex(); // Eat the ')'.
221   
222   Op = X86Operand::CreateMem(SegReg, Disp, BaseReg, Scale, ScaleReg);
223   return false;
224 }
225
226 /// ParseParenExpr - Parse a paren expression and return it.
227 /// NOTE: This assumes the leading '(' has already been consumed.
228 ///
229 /// parenexpr ::= expr)
230 ///
231 bool AsmParser::ParseParenExpr(int64_t &Res) {
232   if (ParseExpression(Res)) return true;
233   if (Lexer.isNot(asmtok::RParen))
234     return TokError("expected ')' in parentheses expression");
235   Lexer.Lex();
236   return false;
237 }
238
239 /// ParsePrimaryExpr - Parse a primary expression and return it.
240 ///  primaryexpr ::= (parenexpr
241 ///  primaryexpr ::= symbol
242 ///  primaryexpr ::= number
243 ///  primaryexpr ::= ~,+,- primaryexpr
244 bool AsmParser::ParsePrimaryExpr(int64_t &Res) {
245   switch (Lexer.getKind()) {
246   default:
247     return TokError("unknown token in expression");
248   case asmtok::Identifier:
249     // This is a label, this should be parsed as part of an expression, to
250     // handle things like LFOO+4
251     Res = 0; // FIXME.
252     Lexer.Lex(); // Eat identifier.
253     return false;
254   case asmtok::IntVal:
255     Res = Lexer.getCurIntVal();
256     Lexer.Lex(); // Eat identifier.
257     return false;
258   case asmtok::LParen:
259     Lexer.Lex(); // Eat the '('.
260     return ParseParenExpr(Res);
261   case asmtok::Tilde:
262   case asmtok::Plus:
263   case asmtok::Minus:
264     Lexer.Lex(); // Eat the operator.
265     return ParsePrimaryExpr(Res);
266   }
267 }
268
269 /// ParseExpression - Parse an expression and return it.
270 /// 
271 ///  expr ::= expr +,- expr          -> lowest.
272 ///  expr ::= expr |,^,&,! expr      -> middle.
273 ///  expr ::= expr *,/,%,<<,>> expr  -> highest.
274 ///  expr ::= primaryexpr
275 ///
276 bool AsmParser::ParseExpression(int64_t &Res) {
277   return ParsePrimaryExpr(Res);
278 }
279   
280   
281   
282   
283 /// ParseStatement:
284 ///   ::= EndOfStatement
285 ///   ::= Label* Directive ...Operands... EndOfStatement
286 ///   ::= Label* Identifier OperandList* EndOfStatement
287 bool AsmParser::ParseStatement() {
288   switch (Lexer.getKind()) {
289   default:
290     return TokError("unexpected token at start of statement");
291   case asmtok::EndOfStatement:
292     Lexer.Lex();
293     return false;
294   case asmtok::Identifier:
295     break;
296   // TODO: Recurse on local labels etc.
297   }
298   
299   // If we have an identifier, handle it as the key symbol.
300   SMLoc IDLoc = Lexer.getLoc();
301   std::string IDVal = Lexer.getCurStrVal();
302   
303   // Consume the identifier, see what is after it.
304   if (Lexer.Lex() == asmtok::Colon) {
305     // identifier ':'   -> Label.
306     Lexer.Lex();
307     return ParseStatement();
308   }
309   
310   // Otherwise, we have a normal instruction or directive.  
311   if (IDVal[0] == '.') {
312     Lexer.PrintMessage(IDLoc, "warning: ignoring directive for now");
313     EatToEndOfStatement();
314     return false;
315   }
316
317   // If it's an instruction, parse an operand list.
318   std::vector<X86Operand> Operands;
319   
320   // Read the first operand, if present.  Note that we require a newline at the
321   // end of file, so we don't have to worry about Eof here.
322   if (Lexer.isNot(asmtok::EndOfStatement)) {
323     X86Operand Op;
324     if (ParseX86Operand(Op))
325       return true;
326     Operands.push_back(Op);
327   }
328
329   while (Lexer.is(asmtok::Comma)) {
330     Lexer.Lex();  // Eat the comma.
331     
332     // Parse and remember the operand.
333     X86Operand Op;
334     if (ParseX86Operand(Op))
335       return true;
336     Operands.push_back(Op);
337   }
338   
339   if (Lexer.isNot(asmtok::EndOfStatement))
340     return TokError("unexpected token in operand list");
341
342   // Eat the end of statement marker.
343   Lexer.Lex();
344   
345   // Instruction is good, process it.
346   outs() << "Found instruction: " << IDVal << " with " << Operands.size()
347          << " operands.\n";
348   
349   // Skip to end of line for now.
350   return false;
351 }