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