delete the fixme too! :)
[oota-llvm.git] / lib / Target / X86 / AsmParser / X86AsmParser.cpp
1 //===-- X86AsmParser.cpp - Parse X86 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 "X86.h"
11 #include "llvm/ADT/SmallVector.h"
12 #include "llvm/ADT/Twine.h"
13 #include "llvm/MC/MCAsmLexer.h"
14 #include "llvm/MC/MCAsmParser.h"
15 #include "llvm/MC/MCStreamer.h"
16 #include "llvm/MC/MCExpr.h"
17 #include "llvm/MC/MCInst.h"
18 #include "llvm/Support/SourceMgr.h"
19 #include "llvm/Target/TargetRegistry.h"
20 #include "llvm/Target/TargetAsmParser.h"
21 using namespace llvm;
22
23 namespace {
24 struct X86Operand;
25
26 class X86ATTAsmParser : public TargetAsmParser {
27   MCAsmParser &Parser;
28
29 private:
30   MCAsmParser &getParser() const { return Parser; }
31
32   MCAsmLexer &getLexer() const { return Parser.getLexer(); }
33
34   void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }
35
36   bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
37
38   bool ParseRegister(X86Operand &Op);
39
40   bool ParseOperand(X86Operand &Op);
41
42   bool ParseMemOperand(X86Operand &Op);
43
44   bool ParseDirectiveWord(unsigned Size, SMLoc L);
45
46   /// @name Auto-generated Match Functions
47   /// {  
48
49   bool MatchInstruction(SmallVectorImpl<X86Operand> &Operands,
50                         MCInst &Inst);
51
52   /// MatchRegisterName - Match the given string to a register name, or 0 if
53   /// there is no match.
54   unsigned MatchRegisterName(const StringRef &Name);
55
56   /// }
57
58 public:
59   X86ATTAsmParser(const Target &T, MCAsmParser &_Parser)
60     : TargetAsmParser(T), Parser(_Parser) {}
61
62   virtual bool ParseInstruction(const StringRef &Name, MCInst &Inst);
63
64   virtual bool ParseDirective(AsmToken DirectiveID);
65 };
66   
67 } // end anonymous namespace
68
69
70 namespace {
71
72 /// X86Operand - Instances of this class represent a parsed X86 machine
73 /// instruction.
74 struct X86Operand {
75   enum {
76     Token,
77     Register,
78     Immediate,
79     Memory
80   } Kind;
81
82   union {
83     struct {
84       const char *Data;
85       unsigned Length;
86     } Tok;
87
88     struct {
89       unsigned RegNo;
90     } Reg;
91
92     struct {
93       const MCExpr *Val;
94     } Imm;
95
96     struct {
97       unsigned SegReg;
98       const MCExpr *Disp;
99       unsigned BaseReg;
100       unsigned IndexReg;
101       unsigned Scale;
102     } Mem;
103   };
104
105   StringRef getToken() const {
106     assert(Kind == Token && "Invalid access!");
107     return StringRef(Tok.Data, Tok.Length);
108   }
109
110   unsigned getReg() const {
111     assert(Kind == Register && "Invalid access!");
112     return Reg.RegNo;
113   }
114
115   const MCExpr *getImm() const {
116     assert(Kind == Immediate && "Invalid access!");
117     return Imm.Val;
118   }
119
120   const MCExpr *getMemDisp() const {
121     assert(Kind == Memory && "Invalid access!");
122     return Mem.Disp;
123   }
124   unsigned getMemSegReg() const {
125     assert(Kind == Memory && "Invalid access!");
126     return Mem.SegReg;
127   }
128   unsigned getMemBaseReg() const {
129     assert(Kind == Memory && "Invalid access!");
130     return Mem.BaseReg;
131   }
132   unsigned getMemIndexReg() const {
133     assert(Kind == Memory && "Invalid access!");
134     return Mem.IndexReg;
135   }
136   unsigned getMemScale() const {
137     assert(Kind == Memory && "Invalid access!");
138     return Mem.Scale;
139   }
140
141   bool isToken() const {return Kind == Token; }
142
143   bool isImm() const { return Kind == Immediate; }
144   
145   bool isImmSExt8() const { 
146     // Accept immediates which fit in 8 bits when sign extended, and
147     // non-absolute immediates.
148     if (!isImm())
149       return false;
150
151     if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm())) {
152       int64_t Value = CE->getValue();
153       return Value == (int64_t) (int8_t) Value;
154     }
155
156     return true;
157   }
158   
159   bool isMem() const { return Kind == Memory; }
160
161   bool isReg() const { return Kind == Register; }
162
163   void addRegOperands(MCInst &Inst, unsigned N) const {
164     assert(N == 1 && "Invalid number of operands!");
165     Inst.addOperand(MCOperand::CreateReg(getReg()));
166   }
167
168   void addImmOperands(MCInst &Inst, unsigned N) const {
169     assert(N == 1 && "Invalid number of operands!");
170     Inst.addOperand(MCOperand::CreateExpr(getImm()));
171   }
172
173   void addImmSExt8Operands(MCInst &Inst, unsigned N) const {
174     // FIXME: Support user customization of the render method.
175     assert(N == 1 && "Invalid number of operands!");
176     Inst.addOperand(MCOperand::CreateExpr(getImm()));
177   }
178
179   void addMemOperands(MCInst &Inst, unsigned N) const {
180     assert((N == 4 || N == 5) && "Invalid number of operands!");
181
182     Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
183     Inst.addOperand(MCOperand::CreateImm(getMemScale()));
184     Inst.addOperand(MCOperand::CreateReg(getMemIndexReg()));
185     Inst.addOperand(MCOperand::CreateExpr(getMemDisp()));
186
187     // FIXME: What a hack.
188     if (N == 5)
189       Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
190   }
191
192   static X86Operand CreateToken(StringRef Str) {
193     X86Operand Res;
194     Res.Kind = Token;
195     Res.Tok.Data = Str.data();
196     Res.Tok.Length = Str.size();
197     return Res;
198   }
199
200   static X86Operand CreateReg(unsigned RegNo) {
201     X86Operand Res;
202     Res.Kind = Register;
203     Res.Reg.RegNo = RegNo;
204     return Res;
205   }
206
207   static X86Operand CreateImm(const MCExpr *Val) {
208     X86Operand Res;
209     Res.Kind = Immediate;
210     Res.Imm.Val = Val;
211     return Res;
212   }
213
214   static X86Operand CreateMem(unsigned SegReg, const MCExpr *Disp,
215                               unsigned BaseReg, unsigned IndexReg,
216                               unsigned Scale) {
217     // We should never just have a displacement, that would be an immediate.
218     assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
219
220     // The scale should always be one of {1,2,4,8}.
221     assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
222            "Invalid scale!");
223     X86Operand Res;
224     Res.Kind = Memory;
225     Res.Mem.SegReg   = SegReg;
226     Res.Mem.Disp     = Disp;
227     Res.Mem.BaseReg  = BaseReg;
228     Res.Mem.IndexReg = IndexReg;
229     Res.Mem.Scale    = Scale;
230     return Res;
231   }
232 };
233
234 } // end anonymous namespace.
235
236
237 bool X86ATTAsmParser::ParseRegister(X86Operand &Op) {
238   const AsmToken &TokPercent = getLexer().getTok();
239   (void)TokPercent; // Avoid warning when assertions are disabled.
240   assert(TokPercent.is(AsmToken::Percent) && "Invalid token kind!");
241   getLexer().Lex(); // Eat percent token.
242
243   const AsmToken &Tok = getLexer().getTok();
244   assert(TokPercent.is(AsmToken::Identifier) && "Invalid token kind!");
245
246   // FIXME: Validate register for the current architecture; we have to do
247   // validation later, so maybe there is no need for this here.
248   unsigned RegNo;
249
250   RegNo = MatchRegisterName(Tok.getString());
251   if (RegNo == 0)
252     return Error(Tok.getLoc(), "invalid register name");
253
254   Op = X86Operand::CreateReg(RegNo);
255   getLexer().Lex(); // Eat identifier token.
256
257   return false;
258 }
259
260 bool X86ATTAsmParser::ParseOperand(X86Operand &Op) {
261   switch (getLexer().getKind()) {
262   default:
263     return ParseMemOperand(Op);
264   case AsmToken::Percent:
265     // FIXME: if a segment register, this could either be just the seg reg, or
266     // the start of a memory operand.
267     return ParseRegister(Op);
268   case AsmToken::Dollar: {
269     // $42 -> immediate.
270     getLexer().Lex();
271     const MCExpr *Val;
272     if (getParser().ParseExpression(Val))
273       return true;
274     Op = X86Operand::CreateImm(Val);
275     return false;
276   }
277   }
278 }
279
280 /// ParseMemOperand: segment: disp(basereg, indexreg, scale)
281 bool X86ATTAsmParser::ParseMemOperand(X86Operand &Op) {
282   // FIXME: If SegReg ':'  (e.g. %gs:), eat and remember.
283   unsigned SegReg = 0;
284   
285   // We have to disambiguate a parenthesized expression "(4+5)" from the start
286   // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)".  The
287   // only way to do this without lookahead is to eat the ( and see what is after
288   // it.
289   const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext());
290   if (getLexer().isNot(AsmToken::LParen)) {
291     if (getParser().ParseExpression(Disp)) return true;
292     
293     // After parsing the base expression we could either have a parenthesized
294     // memory address or not.  If not, return now.  If so, eat the (.
295     if (getLexer().isNot(AsmToken::LParen)) {
296       // Unless we have a segment register, treat this as an immediate.
297       if (SegReg)
298         Op = X86Operand::CreateMem(SegReg, Disp, 0, 0, 1);
299       else
300         Op = X86Operand::CreateImm(Disp);
301       return false;
302     }
303     
304     // Eat the '('.
305     getLexer().Lex();
306   } else {
307     // Okay, we have a '('.  We don't know if this is an expression or not, but
308     // so we have to eat the ( to see beyond it.
309     getLexer().Lex(); // Eat the '('.
310     
311     if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) {
312       // Nothing to do here, fall into the code below with the '(' part of the
313       // memory operand consumed.
314     } else {
315       // It must be an parenthesized expression, parse it now.
316       if (getParser().ParseParenExpression(Disp))
317         return true;
318       
319       // After parsing the base expression we could either have a parenthesized
320       // memory address or not.  If not, return now.  If so, eat the (.
321       if (getLexer().isNot(AsmToken::LParen)) {
322         // Unless we have a segment register, treat this as an immediate.
323         if (SegReg)
324           Op = X86Operand::CreateMem(SegReg, Disp, 0, 0, 1);
325         else
326           Op = X86Operand::CreateImm(Disp);
327         return false;
328       }
329       
330       // Eat the '('.
331       getLexer().Lex();
332     }
333   }
334   
335   // If we reached here, then we just ate the ( of the memory operand.  Process
336   // the rest of the memory operand.
337   unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
338   
339   if (getLexer().is(AsmToken::Percent)) {
340     if (ParseRegister(Op))
341       return true;
342     BaseReg = Op.getReg();
343   }
344   
345   if (getLexer().is(AsmToken::Comma)) {
346     getLexer().Lex(); // Eat the comma.
347
348     // Following the comma we should have either an index register, or a scale
349     // value. We don't support the later form, but we want to parse it
350     // correctly.
351     //
352     // Not that even though it would be completely consistent to support syntax
353     // like "1(%eax,,1)", the assembler doesn't.
354     if (getLexer().is(AsmToken::Percent)) {
355       if (ParseRegister(Op))
356         return true;
357       IndexReg = Op.getReg();
358     
359       if (getLexer().isNot(AsmToken::RParen)) {
360         // Parse the scale amount:
361         //  ::= ',' [scale-expression]
362         if (getLexer().isNot(AsmToken::Comma))
363           return true;
364         getLexer().Lex(); // Eat the comma.
365
366         if (getLexer().isNot(AsmToken::RParen)) {
367           SMLoc Loc = getLexer().getTok().getLoc();
368
369           int64_t ScaleVal;
370           if (getParser().ParseAbsoluteExpression(ScaleVal))
371             return true;
372           
373           // Validate the scale amount.
374           if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8)
375             return Error(Loc, "scale factor in address must be 1, 2, 4 or 8");
376           Scale = (unsigned)ScaleVal;
377         }
378       }
379     } else if (getLexer().isNot(AsmToken::RParen)) {
380       // Otherwise we have the unsupported form of a scale amount without an
381       // index.
382       SMLoc Loc = getLexer().getTok().getLoc();
383
384       int64_t Value;
385       if (getParser().ParseAbsoluteExpression(Value))
386         return true;
387       
388       return Error(Loc, "cannot have scale factor without index register");
389     }
390   }
391   
392   // Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
393   if (getLexer().isNot(AsmToken::RParen))
394     return Error(getLexer().getTok().getLoc(),
395                     "unexpected token in memory operand");
396   getLexer().Lex(); // Eat the ')'.
397   
398   Op = X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale);
399   return false;
400 }
401
402 bool X86ATTAsmParser::ParseInstruction(const StringRef &Name, MCInst &Inst) {
403   SmallVector<X86Operand, 8> Operands;
404
405   Operands.push_back(X86Operand::CreateToken(Name));
406
407   SMLoc Loc = getLexer().getTok().getLoc();
408   if (getLexer().isNot(AsmToken::EndOfStatement)) {
409
410     // Parse '*' modifier.
411     if (getLexer().is(AsmToken::Star)) {
412       getLexer().Lex(); // Eat the star.
413       Operands.push_back(X86Operand::CreateToken("*"));
414     }
415
416     // Read the first operand.
417     Operands.push_back(X86Operand());
418     if (ParseOperand(Operands.back()))
419       return true;
420
421     while (getLexer().is(AsmToken::Comma)) {
422       getLexer().Lex();  // Eat the comma.
423
424       // Parse and remember the operand.
425       Operands.push_back(X86Operand());
426       if (ParseOperand(Operands.back()))
427         return true;
428     }
429   }
430
431   if (!MatchInstruction(Operands, Inst))
432     return false;
433
434   // FIXME: We should give nicer diagnostics about the exact failure.
435
436   Error(Loc, "unrecognized instruction");
437   return true;
438 }
439
440 bool X86ATTAsmParser::ParseDirective(AsmToken DirectiveID) {
441   StringRef IDVal = DirectiveID.getIdentifier();
442   if (IDVal == ".word")
443     return ParseDirectiveWord(2, DirectiveID.getLoc());
444   return true;
445 }
446
447 /// ParseDirectiveWord
448 ///  ::= .word [ expression (, expression)* ]
449 bool X86ATTAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
450   if (getLexer().isNot(AsmToken::EndOfStatement)) {
451     for (;;) {
452       const MCExpr *Value;
453       if (getParser().ParseExpression(Value))
454         return true;
455
456       getParser().getStreamer().EmitValue(Value, Size);
457
458       if (getLexer().is(AsmToken::EndOfStatement))
459         break;
460       
461       // FIXME: Improve diagnostic.
462       if (getLexer().isNot(AsmToken::Comma))
463         return Error(L, "unexpected token in directive");
464       getLexer().Lex();
465     }
466   }
467
468   getLexer().Lex();
469   return false;
470 }
471
472 // Force static initialization.
473 extern "C" void LLVMInitializeX86AsmParser() {
474   RegisterAsmParser<X86ATTAsmParser> X(TheX86_32Target);
475   RegisterAsmParser<X86ATTAsmParser> Y(TheX86_64Target);
476 }
477
478 #include "X86GenAsmMatcher.inc"