llvm-mc/x86: Fix various nit-picky bugs in displacement parsing.
[oota-llvm.git] / tools / llvm-mc / MC-X86Specific.cpp
1 //===- MC-X86Specific.cpp - X86-Specific code for MC ----------------------===//
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 // This file implements X86-specific parsing, encoding and decoding stuff for
11 // MC.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "AsmParser.h"
16 #include "llvm/MC/MCInst.h"
17 #include "llvm/Support/SourceMgr.h"
18 using namespace llvm;
19
20 /// X86Operand - Instances of this class represent one X86 machine instruction.
21 struct AsmParser::X86Operand {
22   enum {
23     Register,
24     Immediate,
25     Memory
26   } Kind;
27   
28   union {
29     struct {
30       unsigned RegNo;
31     } Reg;
32
33     struct {
34       MCValue Val;
35     } Imm;
36     
37     struct {
38       unsigned SegReg;
39       MCValue Disp;
40       unsigned BaseReg;
41       unsigned IndexReg;
42       unsigned Scale;
43     } Mem;
44   };
45   
46   unsigned getReg() const {
47     assert(Kind == Register && "Invalid access!");
48     return Reg.RegNo;
49   }
50
51   static X86Operand CreateReg(unsigned RegNo) {
52     X86Operand Res;
53     Res.Kind = Register;
54     Res.Reg.RegNo = RegNo;
55     return Res;
56   }
57   static X86Operand CreateImm(MCValue Val) {
58     X86Operand Res;
59     Res.Kind = Immediate;
60     Res.Imm.Val = Val;
61     return Res;
62   }
63   static X86Operand CreateMem(unsigned SegReg, MCValue Disp, unsigned BaseReg,
64                               unsigned IndexReg, unsigned Scale) {
65     // If there is no index register, we should never have a scale, and we
66     // should always have a scale (in {1,2,4,8}) if we do.
67     assert(((Scale == 0 && !IndexReg) ||
68             (IndexReg && (Scale == 1 || Scale == 2 || 
69                           Scale == 4 || Scale == 8))) &&
70            "Invalid scale!");
71     X86Operand Res;
72     Res.Kind = Memory;
73     Res.Mem.SegReg   = SegReg;
74     Res.Mem.Disp     = Disp;
75     Res.Mem.BaseReg  = BaseReg;
76     Res.Mem.IndexReg = IndexReg;
77     Res.Mem.Scale    = Scale;
78     return Res;
79   }
80 };
81
82 bool AsmParser::ParseX86Register(X86Operand &Op) {
83   assert(Lexer.getKind() == asmtok::Register && "Invalid token kind!");
84
85   // FIXME: Decode register number.
86   Op = X86Operand::CreateReg(123);
87   Lexer.Lex(); // Eat register token.
88
89   return false;
90 }
91
92 bool AsmParser::ParseX86Operand(X86Operand &Op) {
93   switch (Lexer.getKind()) {
94   default:
95     return ParseX86MemOperand(Op);
96   case asmtok::Register:
97     // FIXME: if a segment register, this could either be just the seg reg, or
98     // the start of a memory operand.
99     return ParseX86Register(Op);
100   case asmtok::Dollar: {
101     // $42 -> immediate.
102     Lexer.Lex();
103     MCValue Val;
104     if (ParseRelocatableExpression(Val))
105       return true;
106     Op = X86Operand::CreateImm(Val);
107     return false;
108   }
109   case asmtok::Star: {
110     Lexer.Lex(); // Eat the star.
111     
112     if (Lexer.is(asmtok::Register)) {
113       if (ParseX86Register(Op))
114         return true;
115     } else if (ParseX86MemOperand(Op))
116       return true;
117
118     // FIXME: Note the '*' in the operand for use by the matcher.
119     return false;
120   }
121   }
122 }
123
124 /// ParseX86MemOperand: segment: disp(basereg, indexreg, scale)
125 bool AsmParser::ParseX86MemOperand(X86Operand &Op) {
126   // FIXME: If SegReg ':'  (e.g. %gs:), eat and remember.
127   unsigned SegReg = 0;
128   
129   // We have to disambiguate a parenthesized expression "(4+5)" from the start
130   // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)".  The
131   // only way to do this without lookahead is to eat the ( and see what is after
132   // it.
133   MCValue Disp = MCValue::get(0, 0, 0);
134   if (Lexer.isNot(asmtok::LParen)) {
135     if (ParseRelocatableExpression(Disp)) return true;
136     
137     // After parsing the base expression we could either have a parenthesized
138     // memory address or not.  If not, return now.  If so, eat the (.
139     if (Lexer.isNot(asmtok::LParen)) {
140       Op = X86Operand::CreateMem(SegReg, Disp, 0, 0, 0);
141       return false;
142     }
143     
144     // Eat the '('.
145     Lexer.Lex();
146   } else {
147     // Okay, we have a '('.  We don't know if this is an expression or not, but
148     // so we have to eat the ( to see beyond it.
149     Lexer.Lex(); // Eat the '('.
150     
151     if (Lexer.is(asmtok::Register) || Lexer.is(asmtok::Comma)) {
152       // Nothing to do here, fall into the code below with the '(' part of the
153       // memory operand consumed.
154     } else {
155       // It must be an parenthesized expression, parse it now.
156       if (ParseParenRelocatableExpression(Disp))
157         return true;
158       
159       // After parsing the base expression we could either have a parenthesized
160       // memory address or not.  If not, return now.  If so, eat the (.
161       if (Lexer.isNot(asmtok::LParen)) {
162         Op = X86Operand::CreateMem(SegReg, Disp, 0, 0, 0);
163         return false;
164       }
165       
166       // Eat the '('.
167       Lexer.Lex();
168     }
169   }
170   
171   // If we reached here, then we just ate the ( of the memory operand.  Process
172   // the rest of the memory operand.
173   unsigned BaseReg = 0, IndexReg = 0, Scale = 0;
174   
175   if (Lexer.is(asmtok::Register)) {
176     if (ParseX86Register(Op))
177       return true;
178     BaseReg = Op.getReg();
179   }
180   
181   if (Lexer.is(asmtok::Comma)) {
182     Lexer.Lex(); // Eat the comma.
183
184     // Following the comma we should have either an index register, or a scale
185     // value. We don't support the later form, but we want to parse it
186     // correctly.
187     //
188     // Not that even though it would be completely consistent to support syntax
189     // like "1(%eax,,1)", the assembler doesn't.
190     if (Lexer.is(asmtok::Register)) {
191       if (ParseX86Register(Op))
192         return true;
193       IndexReg = Op.getReg();
194       Scale = 1;      // If not specified, the scale defaults to 1.
195     
196       if (Lexer.isNot(asmtok::RParen)) {
197         // Parse the scale amount:
198         //  ::= ',' [scale-expression]
199         if (Lexer.isNot(asmtok::Comma))
200           return true;
201         Lexer.Lex(); // Eat the comma.
202
203         if (Lexer.isNot(asmtok::RParen)) {
204           int64_t ScaleVal;
205           if (ParseAbsoluteExpression(ScaleVal))
206             return true;
207           
208           // Validate the scale amount.
209           if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8)
210             return TokError("scale factor in address must be 1, 2, 4 or 8");
211           Scale = (unsigned)ScaleVal;
212         }
213       }
214     } else if (Lexer.isNot(asmtok::RParen)) {
215       // Otherwise we have the unsupported form of a scale amount without an
216       // index.
217       SMLoc Loc = Lexer.getLoc();
218
219       int64_t Value;
220       if (ParseAbsoluteExpression(Value))
221         return true;
222       
223       return Error(Loc, "cannot have scale factor without index register");
224     }
225   }
226   
227   // Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
228   if (Lexer.isNot(asmtok::RParen))
229     return TokError("unexpected token in memory operand");
230   Lexer.Lex(); // Eat the ')'.
231   
232   Op = X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale);
233   return false;
234 }
235
236 /// MatchX86Inst - Convert a parsed instruction name and operand list into a
237 /// concrete instruction.
238 static bool MatchX86Inst(const char *Name, 
239                          llvm::SmallVector<AsmParser::X86Operand, 3> &Operands,
240                          MCInst &Inst) {
241   return false;
242 }
243
244 /// ParseX86InstOperands - Parse the operands of an X86 instruction and return
245 /// them as the operands of an MCInst.
246 bool AsmParser::ParseX86InstOperands(const char *InstName, MCInst &Inst) {
247   llvm::SmallVector<X86Operand, 3> Operands;
248
249   if (Lexer.isNot(asmtok::EndOfStatement)) {
250     // Read the first operand.
251     Operands.push_back(X86Operand());
252     if (ParseX86Operand(Operands.back()))
253       return true;
254     
255     while (Lexer.is(asmtok::Comma)) {
256       Lexer.Lex();  // Eat the comma.
257       
258       // Parse and remember the operand.
259       Operands.push_back(X86Operand());
260       if (ParseX86Operand(Operands.back()))
261         return true;
262     }
263   }
264
265   return MatchX86Inst(InstName, Operands, Inst);
266 }