llvm-mc: Rewrite binary subtraction for relocatable expressions, we can't always
[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 using namespace llvm;
18
19 /// X86Operand - Instances of this class represent one X86 machine instruction.
20 struct AsmParser::X86Operand {
21   enum {
22     Register,
23     Immediate,
24     Memory
25   } Kind;
26   
27   union {
28     struct {
29       unsigned RegNo;
30     } Reg;
31
32     struct {
33       // FIXME: Should be a general expression.
34       int64_t Val;
35     } Imm;
36     
37     struct {
38       unsigned SegReg;
39       int64_t Disp;     // FIXME: Should be a general expression.
40       unsigned BaseReg;
41       unsigned Scale;
42       unsigned ScaleReg;
43     } Mem;
44   };
45   
46   static X86Operand CreateReg(unsigned RegNo) {
47     X86Operand Res;
48     Res.Kind = Register;
49     Res.Reg.RegNo = RegNo;
50     return Res;
51   }
52   static X86Operand CreateImm(int64_t Val) {
53     X86Operand Res;
54     Res.Kind = Immediate;
55     Res.Imm.Val = Val;
56     return Res;
57   }
58   static X86Operand CreateMem(unsigned SegReg, int64_t Disp, unsigned BaseReg,
59                               unsigned Scale, unsigned ScaleReg) {
60     X86Operand Res;
61     Res.Kind = Memory;
62     Res.Mem.SegReg   = SegReg;
63     Res.Mem.Disp     = Disp;
64     Res.Mem.BaseReg  = BaseReg;
65     Res.Mem.Scale    = Scale;
66     Res.Mem.ScaleReg = ScaleReg;
67     return Res;
68   }
69   
70   void AddToMCInst(MCInst &I) {
71     // FIXME: Add in x86 order here.
72   }
73 };
74
75 bool AsmParser::ParseX86Operand(X86Operand &Op) {
76   switch (Lexer.getKind()) {
77   default:
78     return ParseX86MemOperand(Op);
79   case asmtok::Register:
80     // FIXME: Decode reg #.
81     // FIXME: if a segment register, this could either be just the seg reg, or
82     // the start of a memory operand.
83     Op = X86Operand::CreateReg(123);
84     Lexer.Lex(); // Eat register.
85     return false;
86   case asmtok::Dollar: {
87     // $42 -> immediate.
88     Lexer.Lex();
89     int64_t Val;
90     if (ParseAbsoluteExpression(Val))
91       return TokError("expected integer constant");
92     Op = X86Operand::CreateReg(Val);
93     return false;
94   case asmtok::Star:
95     Lexer.Lex(); // Eat the star.
96     
97     if (Lexer.is(asmtok::Register)) {
98       Op = X86Operand::CreateReg(123);
99       Lexer.Lex(); // Eat register.
100     } else if (ParseX86MemOperand(Op))
101       return true;
102
103     // FIXME: Note that these are 'dereferenced' so that clients know the '*' is
104     // there.
105     return false;
106   }
107   }
108 }
109
110 /// ParseX86MemOperand: segment: disp(basereg, indexreg, scale)
111 bool AsmParser::ParseX86MemOperand(X86Operand &Op) {
112   // FIXME: If SegReg ':'  (e.g. %gs:), eat and remember.
113   unsigned SegReg = 0;
114   
115   // We have to disambiguate a parenthesized expression "(4+5)" from the start
116   // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)".  The
117   // only way to do this without lookahead is to eat the ( and see what is after
118   // it.
119   int64_t Disp = 0;
120   if (Lexer.isNot(asmtok::LParen)) {
121     if (ParseAbsoluteExpression(Disp)) return true;
122     
123     // After parsing the base expression we could either have a parenthesized
124     // memory address or not.  If not, return now.  If so, eat the (.
125     if (Lexer.isNot(asmtok::LParen)) {
126       Op = X86Operand::CreateMem(SegReg, Disp, 0, 0, 0);
127       return false;
128     }
129     
130     // Eat the '('.
131     Lexer.Lex();
132   } else {
133     // Okay, we have a '('.  We don't know if this is an expression or not, but
134     // so we have to eat the ( to see beyond it.
135     Lexer.Lex(); // Eat the '('.
136     
137     if (Lexer.is(asmtok::Register) || Lexer.is(asmtok::Comma)) {
138       // Nothing to do here, fall into the code below with the '(' part of the
139       // memory operand consumed.
140     } else {
141       // It must be an parenthesized expression, parse it now.
142       if (ParseAbsoluteExpression(Disp))
143         return true;
144       
145       // After parsing the base expression we could either have a parenthesized
146       // memory address or not.  If not, return now.  If so, eat the (.
147       if (Lexer.isNot(asmtok::LParen)) {
148         Op = X86Operand::CreateMem(SegReg, Disp, 0, 0, 0);
149         return false;
150       }
151       
152       // Eat the '('.
153       Lexer.Lex();
154     }
155   }
156   
157   // If we reached here, then we just ate the ( of the memory operand.  Process
158   // the rest of the memory operand.
159   unsigned BaseReg = 0, ScaleReg = 0, Scale = 0;
160   
161   if (Lexer.is(asmtok::Register)) {
162     BaseReg = 123; // FIXME: decode reg #
163     Lexer.Lex();  // eat the register.
164   }
165   
166   if (Lexer.is(asmtok::Comma)) {
167     Lexer.Lex(); // eat the comma.
168     
169     if (Lexer.is(asmtok::Register)) {
170       ScaleReg = 123; // FIXME: decode reg #
171       Lexer.Lex();  // eat the register.
172       Scale = 1;      // If not specified, the scale defaults to 1.
173     }
174     
175     if (Lexer.is(asmtok::Comma)) {
176       Lexer.Lex(); // eat the comma.
177
178       // If present, get and validate scale amount.
179       if (Lexer.is(asmtok::IntVal)) {
180         int64_t ScaleVal = Lexer.getCurIntVal();
181         if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8)
182           return TokError("scale factor in address must be 1, 2, 4 or 8");
183         Lexer.Lex();  // eat the scale.
184         Scale = (unsigned)ScaleVal;
185       }
186     }
187   }
188   
189   // Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
190   if (Lexer.isNot(asmtok::RParen))
191     return TokError("unexpected token in memory operand");
192   Lexer.Lex(); // Eat the ')'.
193   
194   Op = X86Operand::CreateMem(SegReg, Disp, BaseReg, Scale, ScaleReg);
195   return false;
196 }
197
198 /// ParseX86InstOperands - Parse the operands of an X86 instruction and return
199 /// them as the operands of an MCInst.
200 bool AsmParser::ParseX86InstOperands(MCInst &Inst) {
201   // If no operands are present, just return.
202   if (Lexer.is(asmtok::EndOfStatement))
203     return false;
204
205   // Read the first operand.
206   X86Operand Op;
207   if (ParseX86Operand(Op))
208     return true;
209   Op.AddToMCInst(Inst);
210   
211   while (Lexer.is(asmtok::Comma)) {
212     Lexer.Lex();  // Eat the comma.
213     
214     // Parse and remember the operand.
215     Op = X86Operand();
216     if (ParseX86Operand(Op))
217       return true;
218     Op.AddToMCInst(Inst);
219   }
220   return false;
221 }