1 //===- MC-X86Specific.cpp - X86-Specific code for MC ----------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements X86-specific parsing, encoding and decoding stuff for
13 //===----------------------------------------------------------------------===//
15 #include "AsmParser.h"
16 #include "llvm/MC/MCInst.h"
19 /// X86Operand - Instances of this class represent one X86 machine instruction.
20 struct AsmParser::X86Operand {
33 // FIXME: Should be a general expression.
39 int64_t Disp; // FIXME: Should be a general expression.
46 static X86Operand CreateReg(unsigned RegNo) {
49 Res.Reg.RegNo = RegNo;
52 static X86Operand CreateImm(int64_t Val) {
58 static X86Operand CreateMem(unsigned SegReg, int64_t Disp, unsigned BaseReg,
59 unsigned Scale, unsigned ScaleReg) {
62 Res.Mem.SegReg = SegReg;
64 Res.Mem.BaseReg = BaseReg;
65 Res.Mem.Scale = Scale;
66 Res.Mem.ScaleReg = ScaleReg;
70 void AddToMCInst(MCInst &I) {
71 // FIXME: Add in x86 order here.
75 bool AsmParser::ParseX86Operand(X86Operand &Op) {
76 switch (Lexer.getKind()) {
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.
86 case asmtok::Dollar: {
90 if (ParseAbsoluteExpression(Val))
91 return TokError("expected integer constant");
92 Op = X86Operand::CreateReg(Val);
95 Lexer.Lex(); // Eat the star.
97 if (Lexer.is(asmtok::Register)) {
98 Op = X86Operand::CreateReg(123);
99 Lexer.Lex(); // Eat register.
100 } else if (ParseX86MemOperand(Op))
103 // FIXME: Note that these are 'dereferenced' so that clients know the '*' is
110 /// ParseX86MemOperand: segment: disp(basereg, indexreg, scale)
111 bool AsmParser::ParseX86MemOperand(X86Operand &Op) {
112 // FIXME: If SegReg ':' (e.g. %gs:), eat and remember.
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
120 if (Lexer.isNot(asmtok::LParen)) {
121 if (ParseAbsoluteExpression(Disp)) return true;
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);
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 '('.
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.
141 // It must be an parenthesized expression, parse it now.
142 if (ParseAbsoluteExpression(Disp))
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);
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;
161 if (Lexer.is(asmtok::Register)) {
162 BaseReg = 123; // FIXME: decode reg #
163 Lexer.Lex(); // eat the register.
166 if (Lexer.is(asmtok::Comma)) {
167 Lexer.Lex(); // eat the comma.
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.
175 if (Lexer.is(asmtok::Comma)) {
176 Lexer.Lex(); // eat the comma.
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;
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 ')'.
194 Op = X86Operand::CreateMem(SegReg, Disp, BaseReg, Scale, ScaleReg);
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))
205 // Read the first operand.
207 if (ParseX86Operand(Op))
209 Op.AddToMCInst(Inst);
211 while (Lexer.is(asmtok::Comma)) {
212 Lexer.Lex(); // Eat the comma.
214 // Parse and remember the operand.
216 if (ParseX86Operand(Op))
218 Op.AddToMCInst(Inst);