4d7358ab5843b2e152682b834de662829759c711
[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/MCInst.h"
16 #include "llvm/MC/MCValue.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   bool MatchInstruction(const StringRef &Name,
30                         SmallVectorImpl<X86Operand> &Operands,
31                         MCInst &Inst);
32
33   MCAsmParser &getParser() const { return Parser; }
34
35   MCAsmLexer &getLexer() const { return Parser.getLexer(); }
36
37   void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }
38
39   bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
40
41   bool ParseRegister(X86Operand &Op);
42
43   bool ParseOperand(X86Operand &Op);
44
45   bool ParseMemOperand(X86Operand &Op);
46   
47   /// @name Auto-generated Match Functions
48   /// {  
49
50   bool MatchRegisterName(const StringRef &Name, unsigned &RegNo);
51
52   /// }
53
54 public:
55   X86ATTAsmParser(const Target &T, MCAsmParser &_Parser)
56     : TargetAsmParser(T), Parser(_Parser) {}
57
58   virtual bool ParseInstruction(const StringRef &Name, MCInst &Inst);
59 };
60   
61 } // end anonymous namespace
62
63
64 namespace {
65
66 /// X86Operand - Instances of this class represent a parsed X86 machine
67 /// instruction.
68 struct X86Operand {
69   enum {
70     Register,
71     Immediate,
72     Memory
73   } Kind;
74
75   union {
76     struct {
77       unsigned RegNo;
78     } Reg;
79
80     struct {
81       MCValue Val;
82     } Imm;
83
84     struct {
85       unsigned SegReg;
86       MCValue Disp;
87       unsigned BaseReg;
88       unsigned IndexReg;
89       unsigned Scale;
90     } Mem;
91   };
92
93   unsigned getReg() const {
94     assert(Kind == Register && "Invalid access!");
95     return Reg.RegNo;
96   }
97
98   const MCValue &getImm() const {
99     assert(Kind == Immediate && "Invalid access!");
100     return Imm.Val;
101   }
102
103   const MCValue &getMemDisp() const {
104     assert(Kind == Memory && "Invalid access!");
105     return Mem.Disp;
106   }
107   unsigned getMemSegReg() const {
108     assert(Kind == Memory && "Invalid access!");
109     return Mem.SegReg;
110   }
111   unsigned getMemBaseReg() const {
112     assert(Kind == Memory && "Invalid access!");
113     return Mem.BaseReg;
114   }
115   unsigned getMemIndexReg() const {
116     assert(Kind == Memory && "Invalid access!");
117     return Mem.IndexReg;
118   }
119   unsigned getMemScale() const {
120     assert(Kind == Memory && "Invalid access!");
121     return Mem.Scale;
122   }
123
124   static X86Operand CreateReg(unsigned RegNo) {
125     X86Operand Res;
126     Res.Kind = Register;
127     Res.Reg.RegNo = RegNo;
128     return Res;
129   }
130   static X86Operand CreateImm(MCValue Val) {
131     X86Operand Res;
132     Res.Kind = Immediate;
133     Res.Imm.Val = Val;
134     return Res;
135   }
136   static X86Operand CreateMem(unsigned SegReg, MCValue Disp, unsigned BaseReg,
137                               unsigned IndexReg, unsigned Scale) {
138     // We should never just have a displacement, that would be an immediate.
139     assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
140
141     // The scale should always be one of {1,2,4,8}.
142     assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
143            "Invalid scale!");
144     X86Operand Res;
145     Res.Kind = Memory;
146     Res.Mem.SegReg   = SegReg;
147     Res.Mem.Disp     = Disp;
148     Res.Mem.BaseReg  = BaseReg;
149     Res.Mem.IndexReg = IndexReg;
150     Res.Mem.Scale    = Scale;
151     return Res;
152   }
153 };
154
155 } // end anonymous namespace.
156
157
158 bool X86ATTAsmParser::ParseRegister(X86Operand &Op) {
159   const AsmToken &Tok = getLexer().getTok();
160   assert(Tok.is(AsmToken::Register) && "Invalid token kind!");
161
162   // FIXME: Validate register for the current architecture; we have to do
163   // validation later, so maybe there is no need for this here.
164   unsigned RegNo;
165   assert(Tok.getString().startswith("%") && "Invalid register name!");
166   if (MatchRegisterName(Tok.getString().substr(1), RegNo))
167     return Error(Tok.getLoc(), "invalid register name");
168
169   Op = X86Operand::CreateReg(RegNo);
170   getLexer().Lex(); // Eat register token.
171
172   return false;
173 }
174
175 bool X86ATTAsmParser::ParseOperand(X86Operand &Op) {
176   switch (getLexer().getKind()) {
177   default:
178     return ParseMemOperand(Op);
179   case AsmToken::Register:
180     // FIXME: if a segment register, this could either be just the seg reg, or
181     // the start of a memory operand.
182     return ParseRegister(Op);
183   case AsmToken::Dollar: {
184     // $42 -> immediate.
185     getLexer().Lex();
186     MCValue Val;
187     if (getParser().ParseRelocatableExpression(Val))
188       return true;
189     Op = X86Operand::CreateImm(Val);
190     return false;
191   }
192   case AsmToken::Star:
193     getLexer().Lex(); // Eat the star.
194     
195     if (getLexer().is(AsmToken::Register)) {
196       if (ParseRegister(Op))
197         return true;
198     } else if (ParseMemOperand(Op))
199       return true;
200
201     // FIXME: Note the '*' in the operand for use by the matcher.
202     return false;
203   }
204 }
205
206 /// ParseMemOperand: segment: disp(basereg, indexreg, scale)
207 bool X86ATTAsmParser::ParseMemOperand(X86Operand &Op) {
208   // FIXME: If SegReg ':'  (e.g. %gs:), eat and remember.
209   unsigned SegReg = 0;
210   
211   // We have to disambiguate a parenthesized expression "(4+5)" from the start
212   // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)".  The
213   // only way to do this without lookahead is to eat the ( and see what is after
214   // it.
215   MCValue Disp = MCValue::get(0, 0, 0);
216   if (getLexer().isNot(AsmToken::LParen)) {
217     if (getParser().ParseRelocatableExpression(Disp)) return true;
218     
219     // After parsing the base expression we could either have a parenthesized
220     // memory address or not.  If not, return now.  If so, eat the (.
221     if (getLexer().isNot(AsmToken::LParen)) {
222       // Unless we have a segment register, treat this as an immediate.
223       if (SegReg)
224         Op = X86Operand::CreateMem(SegReg, Disp, 0, 0, 1);
225       else
226         Op = X86Operand::CreateImm(Disp);
227       return false;
228     }
229     
230     // Eat the '('.
231     getLexer().Lex();
232   } else {
233     // Okay, we have a '('.  We don't know if this is an expression or not, but
234     // so we have to eat the ( to see beyond it.
235     getLexer().Lex(); // Eat the '('.
236     
237     if (getLexer().is(AsmToken::Register) || getLexer().is(AsmToken::Comma)) {
238       // Nothing to do here, fall into the code below with the '(' part of the
239       // memory operand consumed.
240     } else {
241       // It must be an parenthesized expression, parse it now.
242       if (getParser().ParseParenRelocatableExpression(Disp))
243         return true;
244       
245       // After parsing the base expression we could either have a parenthesized
246       // memory address or not.  If not, return now.  If so, eat the (.
247       if (getLexer().isNot(AsmToken::LParen)) {
248         // Unless we have a segment register, treat this as an immediate.
249         if (SegReg)
250           Op = X86Operand::CreateMem(SegReg, Disp, 0, 0, 1);
251         else
252           Op = X86Operand::CreateImm(Disp);
253         return false;
254       }
255       
256       // Eat the '('.
257       getLexer().Lex();
258     }
259   }
260   
261   // If we reached here, then we just ate the ( of the memory operand.  Process
262   // the rest of the memory operand.
263   unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
264   
265   if (getLexer().is(AsmToken::Register)) {
266     if (ParseRegister(Op))
267       return true;
268     BaseReg = Op.getReg();
269   }
270   
271   if (getLexer().is(AsmToken::Comma)) {
272     getLexer().Lex(); // Eat the comma.
273
274     // Following the comma we should have either an index register, or a scale
275     // value. We don't support the later form, but we want to parse it
276     // correctly.
277     //
278     // Not that even though it would be completely consistent to support syntax
279     // like "1(%eax,,1)", the assembler doesn't.
280     if (getLexer().is(AsmToken::Register)) {
281       if (ParseRegister(Op))
282         return true;
283       IndexReg = Op.getReg();
284     
285       if (getLexer().isNot(AsmToken::RParen)) {
286         // Parse the scale amount:
287         //  ::= ',' [scale-expression]
288         if (getLexer().isNot(AsmToken::Comma))
289           return true;
290         getLexer().Lex(); // Eat the comma.
291
292         if (getLexer().isNot(AsmToken::RParen)) {
293           SMLoc Loc = getLexer().getTok().getLoc();
294
295           int64_t ScaleVal;
296           if (getParser().ParseAbsoluteExpression(ScaleVal))
297             return true;
298           
299           // Validate the scale amount.
300           if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8)
301             return Error(Loc, "scale factor in address must be 1, 2, 4 or 8");
302           Scale = (unsigned)ScaleVal;
303         }
304       }
305     } else if (getLexer().isNot(AsmToken::RParen)) {
306       // Otherwise we have the unsupported form of a scale amount without an
307       // index.
308       SMLoc Loc = getLexer().getTok().getLoc();
309
310       int64_t Value;
311       if (getParser().ParseAbsoluteExpression(Value))
312         return true;
313       
314       return Error(Loc, "cannot have scale factor without index register");
315     }
316   }
317   
318   // Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
319   if (getLexer().isNot(AsmToken::RParen))
320     return Error(getLexer().getTok().getLoc(),
321                     "unexpected token in memory operand");
322   getLexer().Lex(); // Eat the ')'.
323   
324   Op = X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale);
325   return false;
326 }
327
328 bool X86ATTAsmParser::ParseInstruction(const StringRef &Name, MCInst &Inst) {
329   SmallVector<X86Operand, 3> Operands;
330
331   SMLoc Loc = getLexer().getTok().getLoc();
332   if (getLexer().isNot(AsmToken::EndOfStatement)) {
333     // Read the first operand.
334     Operands.push_back(X86Operand());
335     if (ParseOperand(Operands.back()))
336       return true;
337
338     while (getLexer().is(AsmToken::Comma)) {
339       getLexer().Lex();  // Eat the comma.
340
341       // Parse and remember the operand.
342       Operands.push_back(X86Operand());
343       if (ParseOperand(Operands.back()))
344         return true;
345     }
346   }
347
348   if (!MatchInstruction(Name, Operands, Inst))
349     return false;
350
351   // FIXME: We should give nicer diagnostics about the exact failure.
352
353   // FIXME: For now we just treat unrecognized instructions as "warnings".
354   Warning(Loc, "unrecognized instruction");
355
356   return false;
357 }
358
359 // Force static initialization.
360 extern "C" void LLVMInitializeX86AsmParser() {
361   RegisterAsmParser<X86ATTAsmParser> X(TheX86_32Target);
362   RegisterAsmParser<X86ATTAsmParser> Y(TheX86_64Target);
363 }
364
365 // FIXME: These should come from tblgen?
366
367 static bool 
368 Match_X86_Op_REG(const X86Operand &Op, MCOperand *MCOps, unsigned NumOps) {
369   assert(NumOps == 1 && "Invalid number of ops!");
370
371   // FIXME: Match correct registers.
372   if (Op.Kind != X86Operand::Register)
373     return true;
374
375   MCOps[0] = MCOperand::CreateReg(Op.getReg());
376   return false;
377 }
378
379 static bool 
380 Match_X86_Op_IMM(const X86Operand &Op, MCOperand *MCOps, unsigned NumOps) {
381   assert(NumOps == 1 && "Invalid number of ops!");
382
383   // FIXME: We need to check widths.
384   if (Op.Kind != X86Operand::Immediate)
385     return true;
386
387   MCOps[0] = MCOperand::CreateMCValue(Op.getImm());
388   return false;
389 }
390
391 static bool Match_X86_Op_LMEM(const X86Operand &Op,
392                              MCOperand *MCOps,
393                              unsigned NumMCOps) {
394   assert(NumMCOps == 4 && "Invalid number of ops!");
395
396   if (Op.Kind != X86Operand::Memory)
397     return true;
398
399   MCOps[0] = MCOperand::CreateReg(Op.getMemBaseReg());
400   MCOps[1] = MCOperand::CreateImm(Op.getMemScale());
401   MCOps[2] = MCOperand::CreateReg(Op.getMemIndexReg());
402   MCOps[3] = MCOperand::CreateMCValue(Op.getMemDisp());
403
404   return false;  
405 }
406
407 static bool Match_X86_Op_MEM(const X86Operand &Op,
408                              MCOperand *MCOps,
409                              unsigned NumMCOps) {
410   assert(NumMCOps == 5 && "Invalid number of ops!");
411
412   if (Match_X86_Op_LMEM(Op, MCOps, 4))
413     return true;
414
415   MCOps[4] = MCOperand::CreateReg(Op.getMemSegReg());
416
417   return false;  
418 }
419
420 #define REG(name) \
421   static bool Match_X86_Op_##name(const X86Operand &Op, \
422                                   MCOperand *MCOps,     \
423                                   unsigned NumMCOps) {  \
424     return Match_X86_Op_REG(Op, MCOps, NumMCOps);       \
425   }
426
427 REG(GR64)
428 REG(GR32)
429 REG(GR16)
430 REG(GR8)
431
432 #define IMM(name) \
433   static bool Match_X86_Op_##name(const X86Operand &Op, \
434                                   MCOperand *MCOps,     \
435                                   unsigned NumMCOps) {  \
436     return Match_X86_Op_IMM(Op, MCOps, NumMCOps);       \
437   }
438
439 IMM(brtarget)
440 IMM(brtarget8)
441 IMM(i16i8imm)
442 IMM(i16imm)
443 IMM(i32i8imm)
444 IMM(i32imm)
445 IMM(i32imm_pcrel)
446 IMM(i64i32imm)
447 IMM(i64i32imm_pcrel)
448 IMM(i64i8imm)
449 IMM(i64imm)
450 IMM(i8imm)
451
452 #define LMEM(name) \
453   static bool Match_X86_Op_##name(const X86Operand &Op, \
454                                   MCOperand *MCOps,     \
455                                   unsigned NumMCOps) {  \
456     return Match_X86_Op_LMEM(Op, MCOps, NumMCOps);       \
457   }
458
459 LMEM(lea32mem)
460 LMEM(lea64_32mem)
461 LMEM(lea64mem)
462
463 #define MEM(name) \
464   static bool Match_X86_Op_##name(const X86Operand &Op, \
465                                   MCOperand *MCOps,     \
466                                   unsigned NumMCOps) {  \
467     return Match_X86_Op_MEM(Op, MCOps, NumMCOps);       \
468   }
469
470 MEM(f128mem)
471 MEM(f32mem)
472 MEM(f64mem)
473 MEM(f80mem)
474 MEM(i128mem)
475 MEM(i16mem)
476 MEM(i32mem)
477 MEM(i64mem)
478 MEM(i8mem)
479 MEM(sdmem)
480 MEM(ssmem)
481
482 #define DUMMY(name) \
483   static bool Match_X86_Op_##name(const X86Operand &Op, \
484                                   MCOperand *MCOps,     \
485                                   unsigned NumMCOps) {  \
486     return true;                                        \
487   }
488
489 DUMMY(FR32)
490 DUMMY(FR64)
491 DUMMY(GR32_NOREX)
492 DUMMY(GR8_NOREX)
493 DUMMY(RST)
494 DUMMY(VR128)
495 DUMMY(VR64)
496 DUMMY(i8mem_NOREX)
497
498 #include "X86GenAsmMatcher.inc"