a9f87812cd75d532bb77b49e8a1bc755720d3873
[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 End)
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, SMLoc Loc) {
205     X86Operand *Res = new X86Operand(Token, Loc, Loc);
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, SMLoc StartLoc, SMLoc EndLoc){
218     X86Operand *Res = new X86Operand(Immediate, StartLoc, EndLoc);
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, SMLoc StartLoc, SMLoc EndLoc) {
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, StartLoc, EndLoc);
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     SMLoc Start = getLexer().getTok().getLoc(), End;
283     getLexer().Lex();
284     const MCExpr *Val;
285     if (getParser().ParseExpression(Val, End))
286       return 0;
287     return X86Operand::CreateImm(Val, Start, End);
288   }
289   }
290 }
291
292 /// ParseMemOperand: segment: disp(basereg, indexreg, scale)
293 X86Operand *X86ATTAsmParser::ParseMemOperand() {
294   SMLoc MemStart = getLexer().getTok().getLoc();
295   
296   // FIXME: If SegReg ':'  (e.g. %gs:), eat and remember.
297   unsigned SegReg = 0;
298   
299   // We have to disambiguate a parenthesized expression "(4+5)" from the start
300   // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)".  The
301   // only way to do this without lookahead is to eat the ( and see what is after
302   // it.
303   const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext());
304   if (getLexer().isNot(AsmToken::LParen)) {
305     SMLoc ExprEnd;
306     if (getParser().ParseExpression(Disp, ExprEnd)) return 0;
307     
308     // After parsing the base expression we could either have a parenthesized
309     // memory address or not.  If not, return now.  If so, eat the (.
310     if (getLexer().isNot(AsmToken::LParen)) {
311       // Unless we have a segment register, treat this as an immediate.
312       if (SegReg == 0)
313         return X86Operand::CreateImm(Disp, MemStart, ExprEnd);
314       return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd);
315     }
316     
317     // Eat the '('.
318     getLexer().Lex();
319   } else {
320     // Okay, we have a '('.  We don't know if this is an expression or not, but
321     // so we have to eat the ( to see beyond it.
322     SMLoc LParenLoc = getLexer().getTok().getLoc();
323     getLexer().Lex(); // Eat the '('.
324     
325     if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) {
326       // Nothing to do here, fall into the code below with the '(' part of the
327       // memory operand consumed.
328     } else {
329       SMLoc ExprEnd;
330       
331       // It must be an parenthesized expression, parse it now.
332       if (getParser().ParseParenExpression(Disp, ExprEnd))
333         return 0;
334       
335       // After parsing the base expression we could either have a parenthesized
336       // memory address or not.  If not, return now.  If so, eat the (.
337       if (getLexer().isNot(AsmToken::LParen)) {
338         // Unless we have a segment register, treat this as an immediate.
339         if (SegReg == 0)
340           return X86Operand::CreateImm(Disp, LParenLoc, ExprEnd);
341         return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd);
342       }
343       
344       // Eat the '('.
345       getLexer().Lex();
346     }
347   }
348   
349   // If we reached here, then we just ate the ( of the memory operand.  Process
350   // the rest of the memory operand.
351   unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
352   
353   if (getLexer().is(AsmToken::Percent)) {
354     SMLoc L;
355     if (ParseRegister(BaseReg, L, L)) return 0;
356   }
357   
358   if (getLexer().is(AsmToken::Comma)) {
359     getLexer().Lex(); // Eat the comma.
360
361     // Following the comma we should have either an index register, or a scale
362     // value. We don't support the later form, but we want to parse it
363     // correctly.
364     //
365     // Not that even though it would be completely consistent to support syntax
366     // like "1(%eax,,1)", the assembler doesn't.
367     if (getLexer().is(AsmToken::Percent)) {
368       SMLoc L;
369       if (ParseRegister(IndexReg, L, L)) return 0;
370     
371       if (getLexer().isNot(AsmToken::RParen)) {
372         // Parse the scale amount:
373         //  ::= ',' [scale-expression]
374         if (getLexer().isNot(AsmToken::Comma)) {
375           Error(getLexer().getTok().getLoc(),
376                 "expected comma in scale expression");
377           return 0;
378         }
379         getLexer().Lex(); // Eat the comma.
380
381         if (getLexer().isNot(AsmToken::RParen)) {
382           SMLoc Loc = getLexer().getTok().getLoc();
383
384           int64_t ScaleVal;
385           if (getParser().ParseAbsoluteExpression(ScaleVal))
386             return 0;
387           
388           // Validate the scale amount.
389           if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8){
390             Error(Loc, "scale factor in address must be 1, 2, 4 or 8");
391             return 0;
392           }
393           Scale = (unsigned)ScaleVal;
394         }
395       }
396     } else if (getLexer().isNot(AsmToken::RParen)) {
397       // Otherwise we have the unsupported form of a scale amount without an
398       // index.
399       SMLoc Loc = getLexer().getTok().getLoc();
400
401       int64_t Value;
402       if (getParser().ParseAbsoluteExpression(Value))
403         return 0;
404       
405       Error(Loc, "cannot have scale factor without index register");
406       return 0;
407     }
408   }
409   
410   // Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
411   if (getLexer().isNot(AsmToken::RParen)) {
412     Error(getLexer().getTok().getLoc(), "unexpected token in memory operand");
413     return 0;
414   }
415   SMLoc MemEnd = getLexer().getTok().getLoc();
416   getLexer().Lex(); // Eat the ')'.
417   
418   return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale,
419                                MemStart, MemEnd);
420 }
421
422 bool X86ATTAsmParser::
423 ParseInstruction(const StringRef &Name, SMLoc NameLoc,
424                  SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
425
426   Operands.push_back(X86Operand::CreateToken(Name, NameLoc));
427
428   if (getLexer().isNot(AsmToken::EndOfStatement)) {
429
430     // Parse '*' modifier.
431     if (getLexer().is(AsmToken::Star)) {
432       SMLoc Loc = getLexer().getTok().getLoc();
433       Operands.push_back(X86Operand::CreateToken("*", Loc));
434       getLexer().Lex(); // Eat the star.
435     }
436
437     // Read the first operand.
438     if (X86Operand *Op = ParseOperand())
439       Operands.push_back(Op);
440     else
441       return true;
442     
443     while (getLexer().is(AsmToken::Comma)) {
444       getLexer().Lex();  // Eat the comma.
445
446       // Parse and remember the operand.
447       if (X86Operand *Op = ParseOperand())
448         Operands.push_back(Op);
449       else
450         return true;
451     }
452   }
453
454   return false;
455 }
456
457 bool X86ATTAsmParser::ParseDirective(AsmToken DirectiveID) {
458   StringRef IDVal = DirectiveID.getIdentifier();
459   if (IDVal == ".word")
460     return ParseDirectiveWord(2, DirectiveID.getLoc());
461   return true;
462 }
463
464 /// ParseDirectiveWord
465 ///  ::= .word [ expression (, expression)* ]
466 bool X86ATTAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
467   if (getLexer().isNot(AsmToken::EndOfStatement)) {
468     for (;;) {
469       const MCExpr *Value;
470       if (getParser().ParseExpression(Value))
471         return true;
472
473       getParser().getStreamer().EmitValue(Value, Size, 0 /*addrspace*/);
474
475       if (getLexer().is(AsmToken::EndOfStatement))
476         break;
477       
478       // FIXME: Improve diagnostic.
479       if (getLexer().isNot(AsmToken::Comma))
480         return Error(L, "unexpected token in directive");
481       getLexer().Lex();
482     }
483   }
484
485   getLexer().Lex();
486   return false;
487 }
488
489 // Force static initialization.
490 extern "C" void LLVMInitializeX86AsmParser() {
491   RegisterAsmParser<X86ATTAsmParser> X(TheX86_32Target);
492   RegisterAsmParser<X86ATTAsmParser> Y(TheX86_64Target);
493 }
494
495 #include "X86GenAsmMatcher.inc"