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