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