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