blob: 4a8a63e2847cc1788377bc75a8770891bdb6061a [file] [log] [blame]
Daniel Dunbar092a9dd2009-07-17 20:42:00 +00001//===-- 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
Chris Lattner98986712010-01-14 22:21:20 +000010#include "llvm/Target/TargetAsmParser.h"
Daniel Dunbar4cb1e132009-07-18 23:03:22 +000011#include "X86.h"
Daniel Dunbar54074b52010-07-19 05:44:09 +000012#include "X86Subtarget.h"
Chris Lattner33d60d52010-09-22 04:11:10 +000013#include "llvm/Target/TargetRegistry.h"
14#include "llvm/Target/TargetAsmParser.h"
Kevin Enderby9c656452009-09-10 20:51:44 +000015#include "llvm/MC/MCStreamer.h"
Daniel Dunbar8c2eebe2009-08-31 08:08:38 +000016#include "llvm/MC/MCExpr.h"
Daniel Dunbara027d222009-07-31 02:32:59 +000017#include "llvm/MC/MCInst.h"
Chris Lattnerc6ef2772010-01-22 01:44:57 +000018#include "llvm/MC/MCParser/MCAsmLexer.h"
19#include "llvm/MC/MCParser/MCAsmParser.h"
20#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
Chris Lattner33d60d52010-09-22 04:11:10 +000021#include "llvm/ADT/SmallString.h"
22#include "llvm/ADT/SmallVector.h"
23#include "llvm/ADT/StringExtras.h"
24#include "llvm/ADT/StringSwitch.h"
25#include "llvm/ADT/Twine.h"
Daniel Dunbar16cdcb32009-07-28 22:40:46 +000026#include "llvm/Support/SourceMgr.h"
Daniel Dunbar09062b12010-08-12 00:55:42 +000027#include "llvm/Support/raw_ostream.h"
Daniel Dunbar092a9dd2009-07-17 20:42:00 +000028using namespace llvm;
29
30namespace {
Benjamin Kramerc6b79ac2009-07-31 11:35:26 +000031struct X86Operand;
Daniel Dunbar16cdcb32009-07-28 22:40:46 +000032
33class X86ATTAsmParser : public TargetAsmParser {
34 MCAsmParser &Parser;
Daniel Dunbard73ada72010-07-19 00:33:49 +000035 TargetMachine &TM;
Daniel Dunbar16cdcb32009-07-28 22:40:46 +000036
Daniel Dunbarf98bc632010-03-18 20:06:02 +000037protected:
38 unsigned Is64Bit : 1;
Michael J. Spencerc0c8df32010-10-09 11:00:50 +000039
Daniel Dunbar16cdcb32009-07-28 22:40:46 +000040private:
Daniel Dunbar16cdcb32009-07-28 22:40:46 +000041 MCAsmParser &getParser() const { return Parser; }
42
43 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
44
Daniel Dunbar16cdcb32009-07-28 22:40:46 +000045 bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
46
Chris Lattner29ef9a22010-01-15 18:51:29 +000047 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
Daniel Dunbar16cdcb32009-07-28 22:40:46 +000048
Chris Lattner309264d2010-01-15 18:44:13 +000049 X86Operand *ParseOperand();
Chris Lattnereef6d782010-04-17 18:56:34 +000050 X86Operand *ParseMemOperand(unsigned SegReg, SMLoc StartLoc);
Kevin Enderby9c656452009-09-10 20:51:44 +000051
52 bool ParseDirectiveWord(unsigned Size, SMLoc L);
53
Chris Lattner7036f8b2010-09-29 01:42:58 +000054 bool MatchAndEmitInstruction(SMLoc IDLoc,
Chris Lattner7c51a312010-09-29 01:50:45 +000055 SmallVectorImpl<MCParsedAsmOperand*> &Operands,
Chris Lattner7036f8b2010-09-29 01:42:58 +000056 MCStreamer &Out);
Daniel Dunbar20927f22009-08-07 08:26:05 +000057
Daniel Dunbar54074b52010-07-19 05:44:09 +000058 /// @name Auto-generated Matcher Functions
59 /// {
Michael J. Spencerc0c8df32010-10-09 11:00:50 +000060
Chris Lattner0692ee62010-09-06 19:11:01 +000061#define GET_ASSEMBLER_HEADER
62#include "X86GenAsmMatcher.inc"
Michael J. Spencerc0c8df32010-10-09 11:00:50 +000063
Daniel Dunbar0e2771f2009-07-29 00:02:19 +000064 /// }
Daniel Dunbar16cdcb32009-07-28 22:40:46 +000065
66public:
Chris Lattner9a82e702010-10-30 04:57:14 +000067 X86ATTAsmParser(const Target &T, MCAsmParser &parser, TargetMachine &TM)
68 : TargetAsmParser(T), Parser(parser), TM(TM) {
Michael J. Spencerc0c8df32010-10-09 11:00:50 +000069
Daniel Dunbar54074b52010-07-19 05:44:09 +000070 // Initialize the set of available features.
71 setAvailableFeatures(ComputeAvailableFeatures(
72 &TM.getSubtarget<X86Subtarget>()));
73 }
Daniel Dunbar16cdcb32009-07-28 22:40:46 +000074
Benjamin Kramer38e59892010-07-14 22:38:02 +000075 virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc,
Chris Lattner98986712010-01-14 22:21:20 +000076 SmallVectorImpl<MCParsedAsmOperand*> &Operands);
Kevin Enderby9c656452009-09-10 20:51:44 +000077
78 virtual bool ParseDirective(AsmToken DirectiveID);
Daniel Dunbar16cdcb32009-07-28 22:40:46 +000079};
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +000080
Daniel Dunbarf98bc632010-03-18 20:06:02 +000081class X86_32ATTAsmParser : public X86ATTAsmParser {
82public:
Chris Lattner9a82e702010-10-30 04:57:14 +000083 X86_32ATTAsmParser(const Target &T, MCAsmParser &Parser, TargetMachine &TM)
84 : X86ATTAsmParser(T, Parser, TM) {
Daniel Dunbarf98bc632010-03-18 20:06:02 +000085 Is64Bit = false;
86 }
87};
88
89class X86_64ATTAsmParser : public X86ATTAsmParser {
90public:
Chris Lattner9a82e702010-10-30 04:57:14 +000091 X86_64ATTAsmParser(const Target &T, MCAsmParser &Parser, TargetMachine &TM)
92 : X86ATTAsmParser(T, Parser, TM) {
Daniel Dunbarf98bc632010-03-18 20:06:02 +000093 Is64Bit = true;
94 }
95};
96
Chris Lattner37dfdec2009-07-29 06:33:53 +000097} // end anonymous namespace
98
Sean Callanane9b466d2010-01-23 00:40:33 +000099/// @name Auto-generated Match Functions
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000100/// {
Sean Callanane9b466d2010-01-23 00:40:33 +0000101
Chris Lattnerb8d6e982010-02-09 00:34:28 +0000102static unsigned MatchRegisterName(StringRef Name);
Sean Callanane9b466d2010-01-23 00:40:33 +0000103
104/// }
Chris Lattner37dfdec2009-07-29 06:33:53 +0000105
106namespace {
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000107
108/// X86Operand - Instances of this class represent a parsed X86 machine
109/// instruction.
Chris Lattner45220a82010-01-14 21:20:55 +0000110struct X86Operand : public MCParsedAsmOperand {
Chris Lattner1f19f0f2010-01-15 19:06:59 +0000111 enum KindTy {
Daniel Dunbar20927f22009-08-07 08:26:05 +0000112 Token,
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000113 Register,
114 Immediate,
115 Memory
116 } Kind;
117
Chris Lattner29ef9a22010-01-15 18:51:29 +0000118 SMLoc StartLoc, EndLoc;
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000119
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000120 union {
121 struct {
Daniel Dunbar20927f22009-08-07 08:26:05 +0000122 const char *Data;
123 unsigned Length;
124 } Tok;
125
126 struct {
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000127 unsigned RegNo;
128 } Reg;
129
130 struct {
Daniel Dunbar8c2eebe2009-08-31 08:08:38 +0000131 const MCExpr *Val;
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000132 } Imm;
133
134 struct {
135 unsigned SegReg;
Daniel Dunbar8c2eebe2009-08-31 08:08:38 +0000136 const MCExpr *Disp;
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000137 unsigned BaseReg;
138 unsigned IndexReg;
139 unsigned Scale;
140 } Mem;
Daniel Dunbardbd692a2009-07-20 20:01:54 +0000141 };
Daniel Dunbar092a9dd2009-07-17 20:42:00 +0000142
Chris Lattner0a3c5a52010-01-15 19:33:43 +0000143 X86Operand(KindTy K, SMLoc Start, SMLoc End)
Chris Lattner1f19f0f2010-01-15 19:06:59 +0000144 : Kind(K), StartLoc(Start), EndLoc(End) {}
Daniel Dunbarc918d602010-05-04 16:12:42 +0000145
Chris Lattner1f19f0f2010-01-15 19:06:59 +0000146 /// getStartLoc - Get the location of the first token of this operand.
147 SMLoc getStartLoc() const { return StartLoc; }
148 /// getEndLoc - Get the location of the last token of this operand.
149 SMLoc getEndLoc() const { return EndLoc; }
150
Daniel Dunbarb3cb6962010-08-11 06:37:04 +0000151 virtual void dump(raw_ostream &OS) const {}
152
Daniel Dunbar20927f22009-08-07 08:26:05 +0000153 StringRef getToken() const {
154 assert(Kind == Token && "Invalid access!");
155 return StringRef(Tok.Data, Tok.Length);
156 }
Daniel Dunbarc918d602010-05-04 16:12:42 +0000157 void setTokenValue(StringRef Value) {
158 assert(Kind == Token && "Invalid access!");
159 Tok.Data = Value.data();
160 Tok.Length = Value.size();
161 }
Daniel Dunbar20927f22009-08-07 08:26:05 +0000162
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000163 unsigned getReg() const {
164 assert(Kind == Register && "Invalid access!");
165 return Reg.RegNo;
166 }
Daniel Dunbara2edbab2009-07-28 20:47:52 +0000167
Daniel Dunbar8c2eebe2009-08-31 08:08:38 +0000168 const MCExpr *getImm() const {
Daniel Dunbar022e2a82009-07-31 20:53:16 +0000169 assert(Kind == Immediate && "Invalid access!");
170 return Imm.Val;
171 }
172
Daniel Dunbar8c2eebe2009-08-31 08:08:38 +0000173 const MCExpr *getMemDisp() const {
Daniel Dunbar022e2a82009-07-31 20:53:16 +0000174 assert(Kind == Memory && "Invalid access!");
175 return Mem.Disp;
176 }
177 unsigned getMemSegReg() const {
178 assert(Kind == Memory && "Invalid access!");
179 return Mem.SegReg;
180 }
181 unsigned getMemBaseReg() const {
182 assert(Kind == Memory && "Invalid access!");
183 return Mem.BaseReg;
184 }
185 unsigned getMemIndexReg() const {
186 assert(Kind == Memory && "Invalid access!");
187 return Mem.IndexReg;
188 }
189 unsigned getMemScale() const {
190 assert(Kind == Memory && "Invalid access!");
191 return Mem.Scale;
192 }
193
Daniel Dunbara3741fa2009-08-08 07:50:56 +0000194 bool isToken() const {return Kind == Token; }
Daniel Dunbar20927f22009-08-07 08:26:05 +0000195
196 bool isImm() const { return Kind == Immediate; }
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000197
Daniel Dunbar62e4c672010-05-22 21:02:33 +0000198 bool isImmSExti16i8() const {
Daniel Dunbar5fe63382009-08-09 07:20:21 +0000199 if (!isImm())
200 return false;
201
Daniel Dunbar62e4c672010-05-22 21:02:33 +0000202 // If this isn't a constant expr, just assume it fits and let relaxation
203 // handle it.
204 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
205 if (!CE)
206 return true;
Daniel Dunbar5fe63382009-08-09 07:20:21 +0000207
Daniel Dunbar62e4c672010-05-22 21:02:33 +0000208 // Otherwise, check the value is in a range that makes sense for this
209 // extension.
210 uint64_t Value = CE->getValue();
211 return (( Value <= 0x000000000000007FULL)||
212 (0x000000000000FF80ULL <= Value && Value <= 0x000000000000FFFFULL)||
213 (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
Daniel Dunbar5fe63382009-08-09 07:20:21 +0000214 }
Daniel Dunbar62e4c672010-05-22 21:02:33 +0000215 bool isImmSExti32i8() const {
Daniel Dunbar1fe591d2010-05-20 20:20:39 +0000216 if (!isImm())
217 return false;
218
Daniel Dunbar62e4c672010-05-22 21:02:33 +0000219 // If this isn't a constant expr, just assume it fits and let relaxation
220 // handle it.
221 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
222 if (!CE)
223 return true;
Daniel Dunbar1fe591d2010-05-20 20:20:39 +0000224
Daniel Dunbar62e4c672010-05-22 21:02:33 +0000225 // Otherwise, check the value is in a range that makes sense for this
226 // extension.
227 uint64_t Value = CE->getValue();
228 return (( Value <= 0x000000000000007FULL)||
229 (0x00000000FFFFFF80ULL <= Value && Value <= 0x00000000FFFFFFFFULL)||
230 (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
231 }
232 bool isImmSExti64i8() const {
233 if (!isImm())
234 return false;
235
236 // If this isn't a constant expr, just assume it fits and let relaxation
237 // handle it.
238 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
239 if (!CE)
240 return true;
241
242 // Otherwise, check the value is in a range that makes sense for this
243 // extension.
244 uint64_t Value = CE->getValue();
245 return (( Value <= 0x000000000000007FULL)||
246 (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
247 }
248 bool isImmSExti64i32() const {
249 if (!isImm())
250 return false;
251
252 // If this isn't a constant expr, just assume it fits and let relaxation
253 // handle it.
254 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
255 if (!CE)
256 return true;
257
258 // Otherwise, check the value is in a range that makes sense for this
259 // extension.
260 uint64_t Value = CE->getValue();
261 return (( Value <= 0x000000007FFFFFFFULL)||
262 (0xFFFFFFFF80000000ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
Daniel Dunbar1fe591d2010-05-20 20:20:39 +0000263 }
264
Daniel Dunbar20927f22009-08-07 08:26:05 +0000265 bool isMem() const { return Kind == Memory; }
266
Daniel Dunbarb834f5d2010-01-30 01:02:48 +0000267 bool isAbsMem() const {
268 return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
Daniel Dunbar7b9147a2010-02-02 21:44:16 +0000269 !getMemIndexReg() && getMemScale() == 1;
Daniel Dunbarb834f5d2010-01-30 01:02:48 +0000270 }
271
Daniel Dunbar20927f22009-08-07 08:26:05 +0000272 bool isReg() const { return Kind == Register; }
273
Daniel Dunbar9c60f532010-02-13 00:17:21 +0000274 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
275 // Add as immediates when possible.
276 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
277 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
278 else
279 Inst.addOperand(MCOperand::CreateExpr(Expr));
280 }
281
Daniel Dunbar5c468e32009-08-10 21:00:45 +0000282 void addRegOperands(MCInst &Inst, unsigned N) const {
Daniel Dunbar20927f22009-08-07 08:26:05 +0000283 assert(N == 1 && "Invalid number of operands!");
284 Inst.addOperand(MCOperand::CreateReg(getReg()));
285 }
286
Daniel Dunbar5c468e32009-08-10 21:00:45 +0000287 void addImmOperands(MCInst &Inst, unsigned N) const {
Daniel Dunbar20927f22009-08-07 08:26:05 +0000288 assert(N == 1 && "Invalid number of operands!");
Daniel Dunbar9c60f532010-02-13 00:17:21 +0000289 addExpr(Inst, getImm());
Daniel Dunbar20927f22009-08-07 08:26:05 +0000290 }
291
Daniel Dunbar5c468e32009-08-10 21:00:45 +0000292 void addMemOperands(MCInst &Inst, unsigned N) const {
Daniel Dunbarec2b1f12010-01-30 00:24:00 +0000293 assert((N == 5) && "Invalid number of operands!");
Daniel Dunbar20927f22009-08-07 08:26:05 +0000294 Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
295 Inst.addOperand(MCOperand::CreateImm(getMemScale()));
296 Inst.addOperand(MCOperand::CreateReg(getMemIndexReg()));
Daniel Dunbar9c60f532010-02-13 00:17:21 +0000297 addExpr(Inst, getMemDisp());
Daniel Dunbarec2b1f12010-01-30 00:24:00 +0000298 Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
299 }
Daniel Dunbar20927f22009-08-07 08:26:05 +0000300
Daniel Dunbarb834f5d2010-01-30 01:02:48 +0000301 void addAbsMemOperands(MCInst &Inst, unsigned N) const {
302 assert((N == 1) && "Invalid number of operands!");
303 Inst.addOperand(MCOperand::CreateExpr(getMemDisp()));
304 }
305
Chris Lattnerb4307b32010-01-15 19:28:38 +0000306 static X86Operand *CreateToken(StringRef Str, SMLoc Loc) {
307 X86Operand *Res = new X86Operand(Token, Loc, Loc);
Chris Lattner29ef9a22010-01-15 18:51:29 +0000308 Res->Tok.Data = Str.data();
309 Res->Tok.Length = Str.size();
Daniel Dunbar20927f22009-08-07 08:26:05 +0000310 return Res;
311 }
312
Chris Lattner29ef9a22010-01-15 18:51:29 +0000313 static X86Operand *CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc) {
Chris Lattner1f19f0f2010-01-15 19:06:59 +0000314 X86Operand *Res = new X86Operand(Register, StartLoc, EndLoc);
Chris Lattner29ef9a22010-01-15 18:51:29 +0000315 Res->Reg.RegNo = RegNo;
Chris Lattner29ef9a22010-01-15 18:51:29 +0000316 return Res;
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000317 }
Daniel Dunbar20927f22009-08-07 08:26:05 +0000318
Chris Lattnerb4307b32010-01-15 19:28:38 +0000319 static X86Operand *CreateImm(const MCExpr *Val, SMLoc StartLoc, SMLoc EndLoc){
320 X86Operand *Res = new X86Operand(Immediate, StartLoc, EndLoc);
Chris Lattner29ef9a22010-01-15 18:51:29 +0000321 Res->Imm.Val = Val;
322 return Res;
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000323 }
Daniel Dunbar20927f22009-08-07 08:26:05 +0000324
Daniel Dunbarb834f5d2010-01-30 01:02:48 +0000325 /// Create an absolute memory operand.
326 static X86Operand *CreateMem(const MCExpr *Disp, SMLoc StartLoc,
327 SMLoc EndLoc) {
328 X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc);
329 Res->Mem.SegReg = 0;
330 Res->Mem.Disp = Disp;
331 Res->Mem.BaseReg = 0;
332 Res->Mem.IndexReg = 0;
Daniel Dunbar7b9147a2010-02-02 21:44:16 +0000333 Res->Mem.Scale = 1;
Daniel Dunbarb834f5d2010-01-30 01:02:48 +0000334 return Res;
335 }
336
337 /// Create a generalized memory operand.
Chris Lattner309264d2010-01-15 18:44:13 +0000338 static X86Operand *CreateMem(unsigned SegReg, const MCExpr *Disp,
339 unsigned BaseReg, unsigned IndexReg,
Chris Lattner0a3c5a52010-01-15 19:33:43 +0000340 unsigned Scale, SMLoc StartLoc, SMLoc EndLoc) {
Daniel Dunbarb834f5d2010-01-30 01:02:48 +0000341 // We should never just have a displacement, that should be parsed as an
342 // absolute memory operand.
Daniel Dunbarc09e4112009-07-31 22:22:54 +0000343 assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
344
Daniel Dunbar022e2a82009-07-31 20:53:16 +0000345 // The scale should always be one of {1,2,4,8}.
346 assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000347 "Invalid scale!");
Chris Lattner0a3c5a52010-01-15 19:33:43 +0000348 X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc);
Chris Lattner29ef9a22010-01-15 18:51:29 +0000349 Res->Mem.SegReg = SegReg;
350 Res->Mem.Disp = Disp;
351 Res->Mem.BaseReg = BaseReg;
352 Res->Mem.IndexReg = IndexReg;
353 Res->Mem.Scale = Scale;
354 return Res;
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000355 }
356};
Daniel Dunbara3af3702009-07-20 18:55:04 +0000357
Chris Lattner37dfdec2009-07-29 06:33:53 +0000358} // end anonymous namespace.
Daniel Dunbara2edbab2009-07-28 20:47:52 +0000359
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000360
Chris Lattner29ef9a22010-01-15 18:51:29 +0000361bool X86ATTAsmParser::ParseRegister(unsigned &RegNo,
362 SMLoc &StartLoc, SMLoc &EndLoc) {
Chris Lattner23075742010-01-15 18:27:19 +0000363 RegNo = 0;
Sean Callanan18b83232010-01-19 21:44:56 +0000364 const AsmToken &TokPercent = Parser.getTok();
Kevin Enderby7b4608d2009-09-03 17:15:07 +0000365 assert(TokPercent.is(AsmToken::Percent) && "Invalid token kind!");
Chris Lattner29ef9a22010-01-15 18:51:29 +0000366 StartLoc = TokPercent.getLoc();
Sean Callananb9a25b72010-01-19 20:27:46 +0000367 Parser.Lex(); // Eat percent token.
Kevin Enderby7b4608d2009-09-03 17:15:07 +0000368
Sean Callanan18b83232010-01-19 21:44:56 +0000369 const AsmToken &Tok = Parser.getTok();
Kevin Enderby0d6cd002009-09-16 17:18:29 +0000370 if (Tok.isNot(AsmToken::Identifier))
371 return Error(Tok.getLoc(), "invalid register name");
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000372
Daniel Dunbar0e2771f2009-07-29 00:02:19 +0000373 // FIXME: Validate register for the current architecture; we have to do
374 // validation later, so maybe there is no need for this here.
Kevin Enderby7b4608d2009-09-03 17:15:07 +0000375 RegNo = MatchRegisterName(Tok.getString());
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000376
Chris Lattner33d60d52010-09-22 04:11:10 +0000377 // If the match failed, try the register name as lowercase.
378 if (RegNo == 0)
379 RegNo = MatchRegisterName(LowercaseString(Tok.getString()));
Michael J. Spencerc0c8df32010-10-09 11:00:50 +0000380
Bruno Cardoso Lopes3c8e1be2010-07-24 00:06:39 +0000381 // FIXME: This should be done using Requires<In32BitMode> and
382 // Requires<In64BitMode> so "eiz" usage in 64-bit instructions
383 // can be also checked.
384 if (RegNo == X86::RIZ && !Is64Bit)
385 return Error(Tok.getLoc(), "riz register in 64-bit mode only");
386
Chris Lattner33d60d52010-09-22 04:11:10 +0000387 // Parse "%st" as "%st(0)" and "%st(1)", which is multiple tokens.
388 if (RegNo == 0 && (Tok.getString() == "st" || Tok.getString() == "ST")) {
Chris Lattnere16b0fc2010-02-09 00:49:22 +0000389 RegNo = X86::ST0;
390 EndLoc = Tok.getLoc();
391 Parser.Lex(); // Eat 'st'
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000392
Chris Lattnere16b0fc2010-02-09 00:49:22 +0000393 // Check to see if we have '(4)' after %st.
394 if (getLexer().isNot(AsmToken::LParen))
395 return false;
396 // Lex the paren.
397 getParser().Lex();
398
399 const AsmToken &IntTok = Parser.getTok();
400 if (IntTok.isNot(AsmToken::Integer))
401 return Error(IntTok.getLoc(), "expected stack index");
402 switch (IntTok.getIntVal()) {
403 case 0: RegNo = X86::ST0; break;
404 case 1: RegNo = X86::ST1; break;
405 case 2: RegNo = X86::ST2; break;
406 case 3: RegNo = X86::ST3; break;
407 case 4: RegNo = X86::ST4; break;
408 case 5: RegNo = X86::ST5; break;
409 case 6: RegNo = X86::ST6; break;
410 case 7: RegNo = X86::ST7; break;
411 default: return Error(IntTok.getLoc(), "invalid stack index");
412 }
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000413
Chris Lattnere16b0fc2010-02-09 00:49:22 +0000414 if (getParser().Lex().isNot(AsmToken::RParen))
415 return Error(Parser.getTok().getLoc(), "expected ')'");
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000416
Chris Lattnere16b0fc2010-02-09 00:49:22 +0000417 EndLoc = Tok.getLoc();
418 Parser.Lex(); // Eat ')'
419 return false;
420 }
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000421
Chris Lattner645b2092010-06-24 07:29:18 +0000422 // If this is "db[0-7]", match it as an alias
423 // for dr[0-7].
424 if (RegNo == 0 && Tok.getString().size() == 3 &&
425 Tok.getString().startswith("db")) {
426 switch (Tok.getString()[2]) {
427 case '0': RegNo = X86::DR0; break;
428 case '1': RegNo = X86::DR1; break;
429 case '2': RegNo = X86::DR2; break;
430 case '3': RegNo = X86::DR3; break;
431 case '4': RegNo = X86::DR4; break;
432 case '5': RegNo = X86::DR5; break;
433 case '6': RegNo = X86::DR6; break;
434 case '7': RegNo = X86::DR7; break;
435 }
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000436
Chris Lattner645b2092010-06-24 07:29:18 +0000437 if (RegNo != 0) {
438 EndLoc = Tok.getLoc();
439 Parser.Lex(); // Eat it.
440 return false;
441 }
442 }
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000443
Daniel Dunbar245f0582009-08-08 21:22:41 +0000444 if (RegNo == 0)
Daniel Dunbar0e2771f2009-07-29 00:02:19 +0000445 return Error(Tok.getLoc(), "invalid register name");
446
Chris Lattner29ef9a22010-01-15 18:51:29 +0000447 EndLoc = Tok.getLoc();
Sean Callananb9a25b72010-01-19 20:27:46 +0000448 Parser.Lex(); // Eat identifier token.
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000449 return false;
Daniel Dunbar092a9dd2009-07-17 20:42:00 +0000450}
451
Chris Lattner309264d2010-01-15 18:44:13 +0000452X86Operand *X86ATTAsmParser::ParseOperand() {
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000453 switch (getLexer().getKind()) {
454 default:
Chris Lattnereef6d782010-04-17 18:56:34 +0000455 // Parse a memory operand with no segment register.
456 return ParseMemOperand(0, Parser.getTok().getLoc());
Chris Lattner23075742010-01-15 18:27:19 +0000457 case AsmToken::Percent: {
Chris Lattnereef6d782010-04-17 18:56:34 +0000458 // Read the register.
Chris Lattner23075742010-01-15 18:27:19 +0000459 unsigned RegNo;
Chris Lattner29ef9a22010-01-15 18:51:29 +0000460 SMLoc Start, End;
461 if (ParseRegister(RegNo, Start, End)) return 0;
Bruno Cardoso Lopes3c8e1be2010-07-24 00:06:39 +0000462 if (RegNo == X86::EIZ || RegNo == X86::RIZ) {
463 Error(Start, "eiz and riz can only be used as index registers");
464 return 0;
465 }
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000466
Chris Lattnereef6d782010-04-17 18:56:34 +0000467 // If this is a segment register followed by a ':', then this is the start
468 // of a memory reference, otherwise this is a normal register reference.
469 if (getLexer().isNot(AsmToken::Colon))
470 return X86Operand::CreateReg(RegNo, Start, End);
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000471
472
Chris Lattnereef6d782010-04-17 18:56:34 +0000473 getParser().Lex(); // Eat the colon.
474 return ParseMemOperand(RegNo, Start);
Chris Lattner23075742010-01-15 18:27:19 +0000475 }
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000476 case AsmToken::Dollar: {
477 // $42 -> immediate.
Sean Callanan18b83232010-01-19 21:44:56 +0000478 SMLoc Start = Parser.getTok().getLoc(), End;
Sean Callananb9a25b72010-01-19 20:27:46 +0000479 Parser.Lex();
Daniel Dunbar8c2eebe2009-08-31 08:08:38 +0000480 const MCExpr *Val;
Chris Lattner54482b42010-01-15 19:39:23 +0000481 if (getParser().ParseExpression(Val, End))
Chris Lattner309264d2010-01-15 18:44:13 +0000482 return 0;
Chris Lattnerb4307b32010-01-15 19:28:38 +0000483 return X86Operand::CreateImm(Val, Start, End);
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000484 }
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000485 }
Daniel Dunbardbd692a2009-07-20 20:01:54 +0000486}
487
Chris Lattnereef6d782010-04-17 18:56:34 +0000488/// ParseMemOperand: segment: disp(basereg, indexreg, scale). The '%ds:' prefix
489/// has already been parsed if present.
490X86Operand *X86ATTAsmParser::ParseMemOperand(unsigned SegReg, SMLoc MemStart) {
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000491
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000492 // We have to disambiguate a parenthesized expression "(4+5)" from the start
493 // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)". The
Chris Lattner75f265f2010-01-24 01:07:33 +0000494 // only way to do this without lookahead is to eat the '(' and see what is
495 // after it.
Daniel Dunbar8c2eebe2009-08-31 08:08:38 +0000496 const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext());
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000497 if (getLexer().isNot(AsmToken::LParen)) {
Chris Lattner54482b42010-01-15 19:39:23 +0000498 SMLoc ExprEnd;
499 if (getParser().ParseExpression(Disp, ExprEnd)) return 0;
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000500
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000501 // After parsing the base expression we could either have a parenthesized
502 // memory address or not. If not, return now. If so, eat the (.
503 if (getLexer().isNot(AsmToken::LParen)) {
Daniel Dunbarc09e4112009-07-31 22:22:54 +0000504 // Unless we have a segment register, treat this as an immediate.
Chris Lattner309264d2010-01-15 18:44:13 +0000505 if (SegReg == 0)
Daniel Dunbarb834f5d2010-01-30 01:02:48 +0000506 return X86Operand::CreateMem(Disp, MemStart, ExprEnd);
Chris Lattner0a3c5a52010-01-15 19:33:43 +0000507 return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd);
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000508 }
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000509
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000510 // Eat the '('.
Sean Callananb9a25b72010-01-19 20:27:46 +0000511 Parser.Lex();
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000512 } else {
513 // Okay, we have a '('. We don't know if this is an expression or not, but
514 // so we have to eat the ( to see beyond it.
Sean Callanan18b83232010-01-19 21:44:56 +0000515 SMLoc LParenLoc = Parser.getTok().getLoc();
Sean Callananb9a25b72010-01-19 20:27:46 +0000516 Parser.Lex(); // Eat the '('.
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000517
Kevin Enderby7b4608d2009-09-03 17:15:07 +0000518 if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) {
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000519 // Nothing to do here, fall into the code below with the '(' part of the
520 // memory operand consumed.
521 } else {
Chris Lattnerb4307b32010-01-15 19:28:38 +0000522 SMLoc ExprEnd;
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000523
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000524 // It must be an parenthesized expression, parse it now.
Chris Lattnerb4307b32010-01-15 19:28:38 +0000525 if (getParser().ParseParenExpression(Disp, ExprEnd))
Chris Lattner309264d2010-01-15 18:44:13 +0000526 return 0;
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000527
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000528 // After parsing the base expression we could either have a parenthesized
529 // memory address or not. If not, return now. If so, eat the (.
530 if (getLexer().isNot(AsmToken::LParen)) {
Daniel Dunbarc09e4112009-07-31 22:22:54 +0000531 // Unless we have a segment register, treat this as an immediate.
Chris Lattner309264d2010-01-15 18:44:13 +0000532 if (SegReg == 0)
Daniel Dunbarb834f5d2010-01-30 01:02:48 +0000533 return X86Operand::CreateMem(Disp, LParenLoc, ExprEnd);
Chris Lattner0a3c5a52010-01-15 19:33:43 +0000534 return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd);
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000535 }
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000536
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000537 // Eat the '('.
Sean Callananb9a25b72010-01-19 20:27:46 +0000538 Parser.Lex();
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000539 }
540 }
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000541
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000542 // If we reached here, then we just ate the ( of the memory operand. Process
543 // the rest of the memory operand.
Daniel Dunbar022e2a82009-07-31 20:53:16 +0000544 unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000545
Chris Lattner29ef9a22010-01-15 18:51:29 +0000546 if (getLexer().is(AsmToken::Percent)) {
547 SMLoc L;
548 if (ParseRegister(BaseReg, L, L)) return 0;
Bruno Cardoso Lopes3c8e1be2010-07-24 00:06:39 +0000549 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ) {
550 Error(L, "eiz and riz can only be used as index registers");
551 return 0;
552 }
Chris Lattner29ef9a22010-01-15 18:51:29 +0000553 }
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000554
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000555 if (getLexer().is(AsmToken::Comma)) {
Sean Callananb9a25b72010-01-19 20:27:46 +0000556 Parser.Lex(); // Eat the comma.
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000557
558 // Following the comma we should have either an index register, or a scale
559 // value. We don't support the later form, but we want to parse it
560 // correctly.
561 //
562 // Not that even though it would be completely consistent to support syntax
Bruno Cardoso Lopes3c8e1be2010-07-24 00:06:39 +0000563 // like "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this.
Kevin Enderby7b4608d2009-09-03 17:15:07 +0000564 if (getLexer().is(AsmToken::Percent)) {
Chris Lattner29ef9a22010-01-15 18:51:29 +0000565 SMLoc L;
566 if (ParseRegister(IndexReg, L, L)) return 0;
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000567
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000568 if (getLexer().isNot(AsmToken::RParen)) {
569 // Parse the scale amount:
570 // ::= ',' [scale-expression]
Chris Lattner309264d2010-01-15 18:44:13 +0000571 if (getLexer().isNot(AsmToken::Comma)) {
Sean Callanan18b83232010-01-19 21:44:56 +0000572 Error(Parser.getTok().getLoc(),
Chris Lattner309264d2010-01-15 18:44:13 +0000573 "expected comma in scale expression");
574 return 0;
575 }
Sean Callananb9a25b72010-01-19 20:27:46 +0000576 Parser.Lex(); // Eat the comma.
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000577
578 if (getLexer().isNot(AsmToken::RParen)) {
Sean Callanan18b83232010-01-19 21:44:56 +0000579 SMLoc Loc = Parser.getTok().getLoc();
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000580
581 int64_t ScaleVal;
582 if (getParser().ParseAbsoluteExpression(ScaleVal))
Chris Lattner309264d2010-01-15 18:44:13 +0000583 return 0;
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000584
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000585 // Validate the scale amount.
Chris Lattner309264d2010-01-15 18:44:13 +0000586 if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8){
587 Error(Loc, "scale factor in address must be 1, 2, 4 or 8");
588 return 0;
589 }
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000590 Scale = (unsigned)ScaleVal;
591 }
592 }
593 } else if (getLexer().isNot(AsmToken::RParen)) {
Daniel Dunbaree910252010-08-24 19:13:38 +0000594 // A scale amount without an index is ignored.
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000595 // index.
Sean Callanan18b83232010-01-19 21:44:56 +0000596 SMLoc Loc = Parser.getTok().getLoc();
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000597
598 int64_t Value;
599 if (getParser().ParseAbsoluteExpression(Value))
Chris Lattner309264d2010-01-15 18:44:13 +0000600 return 0;
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000601
Daniel Dunbaree910252010-08-24 19:13:38 +0000602 if (Value != 1)
603 Warning(Loc, "scale factor without index register is ignored");
604 Scale = 1;
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000605 }
606 }
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000607
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000608 // Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
Chris Lattner309264d2010-01-15 18:44:13 +0000609 if (getLexer().isNot(AsmToken::RParen)) {
Sean Callanan18b83232010-01-19 21:44:56 +0000610 Error(Parser.getTok().getLoc(), "unexpected token in memory operand");
Chris Lattner309264d2010-01-15 18:44:13 +0000611 return 0;
612 }
Sean Callanan18b83232010-01-19 21:44:56 +0000613 SMLoc MemEnd = Parser.getTok().getLoc();
Sean Callananb9a25b72010-01-19 20:27:46 +0000614 Parser.Lex(); // Eat the ')'.
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000615
Chris Lattner0a3c5a52010-01-15 19:33:43 +0000616 return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale,
617 MemStart, MemEnd);
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000618}
619
Chris Lattner98986712010-01-14 22:21:20 +0000620bool X86ATTAsmParser::
Benjamin Kramer38e59892010-07-14 22:38:02 +0000621ParseInstruction(StringRef Name, SMLoc NameLoc,
Chris Lattner98986712010-01-14 22:21:20 +0000622 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Daniel Dunbar1b6c0602010-02-10 21:19:28 +0000623 // FIXME: Hack to recognize "sal..." and "rep..." for now. We need a way to
624 // represent alternative syntaxes in the .td file, without requiring
625 // instruction duplication.
626 StringRef PatchedName = StringSwitch<StringRef>(Name)
627 .Case("sal", "shl")
628 .Case("salb", "shlb")
629 .Case("sall", "shll")
630 .Case("salq", "shlq")
631 .Case("salw", "shlw")
632 .Case("repe", "rep")
633 .Case("repz", "rep")
634 .Case("repnz", "repne")
Chris Lattnerba8cea42010-09-08 05:38:31 +0000635 .Case("iret", "iretl")
Chris Lattnerba8e81c2010-09-08 05:45:34 +0000636 .Case("sysret", "sysretl")
Chris Lattner29564622010-09-27 07:24:57 +0000637 .Case("cbw", "cbtw")
638 .Case("cwd", "cwtd")
639 .Case("cdq", "cltd")
Chris Lattnerb1162fc2010-09-27 07:21:41 +0000640 .Case("cwde", "cwtl")
641 .Case("cdqe", "cltq")
Chris Lattnerdf967d62010-09-27 07:11:53 +0000642 .Case("smovb", "movsb")
643 .Case("smovw", "movsw")
644 .Case("smovl", "movsl")
645 .Case("smovq", "movsq")
Chris Lattnerd68c4742010-09-06 23:40:56 +0000646 .Case("push", Is64Bit ? "pushq" : "pushl")
Chris Lattner373c4582010-09-08 22:13:08 +0000647 .Case("pop", Is64Bit ? "popq" : "popl")
Dan Gohmane5e4ff92010-05-20 16:16:00 +0000648 .Case("pushf", Is64Bit ? "pushfq" : "pushfl")
649 .Case("popf", Is64Bit ? "popfq" : "popfl")
Chris Lattnerdfa3c9d2010-09-11 16:39:16 +0000650 .Case("pushfd", "pushfl")
651 .Case("popfd", "popfl")
Kevin Enderby9d31d792010-05-21 23:01:38 +0000652 .Case("retl", Is64Bit ? "retl" : "ret")
653 .Case("retq", Is64Bit ? "ret" : "retq")
Chris Lattner697d37a2010-09-11 17:06:05 +0000654 .Case("setz", "sete") .Case("setnz", "setne")
655 .Case("setc", "setb") .Case("setna", "setbe")
656 .Case("setnae", "setb").Case("setnb", "setae")
657 .Case("setnbe", "seta").Case("setnc", "setae")
658 .Case("setng", "setle").Case("setnge", "setl")
659 .Case("setnl", "setge").Case("setnle", "setg")
660 .Case("setpe", "setp") .Case("setpo", "setnp")
661 .Case("jz", "je") .Case("jnz", "jne")
662 .Case("jc", "jb") .Case("jna", "jbe")
663 .Case("jnae", "jb").Case("jnb", "jae")
664 .Case("jnbe", "ja").Case("jnc", "jae")
665 .Case("jng", "jle").Case("jnge", "jl")
666 .Case("jnl", "jge").Case("jnle", "jg")
667 .Case("jpe", "jp") .Case("jpo", "jnp")
Chris Lattnere9e0fc52010-09-07 00:05:45 +0000668 // Condition code aliases for 16-bit, 32-bit, 64-bit and unspec operands.
669 .Case("cmovcw", "cmovbw") .Case("cmovcl", "cmovbl")
670 .Case("cmovcq", "cmovbq") .Case("cmovc", "cmovb")
Chris Lattner0989d292010-09-11 17:08:22 +0000671 .Case("cmovnaew","cmovbw") .Case("cmovnael","cmovbl")
672 .Case("cmovnaeq","cmovbq") .Case("cmovnae", "cmovb")
Chris Lattnere9e0fc52010-09-07 00:05:45 +0000673 .Case("cmovnaw", "cmovbew").Case("cmovnal", "cmovbel")
674 .Case("cmovnaq", "cmovbeq").Case("cmovna", "cmovbe")
675 .Case("cmovnbw", "cmovaew").Case("cmovnbl", "cmovael")
676 .Case("cmovnbq", "cmovaeq").Case("cmovnb", "cmovae")
677 .Case("cmovnbew","cmovaw") .Case("cmovnbel","cmoval")
678 .Case("cmovnbeq","cmovaq") .Case("cmovnbe", "cmova")
679 .Case("cmovncw", "cmovaew").Case("cmovncl", "cmovael")
680 .Case("cmovncq", "cmovaeq").Case("cmovnc", "cmovae")
681 .Case("cmovngw", "cmovlew").Case("cmovngl", "cmovlel")
682 .Case("cmovngq", "cmovleq").Case("cmovng", "cmovle")
683 .Case("cmovnw", "cmovgew").Case("cmovnl", "cmovgel")
684 .Case("cmovnq", "cmovgeq").Case("cmovn", "cmovge")
685 .Case("cmovngw", "cmovlew").Case("cmovngl", "cmovlel")
686 .Case("cmovngq", "cmovleq").Case("cmovng", "cmovle")
687 .Case("cmovngew","cmovlw") .Case("cmovngel","cmovll")
688 .Case("cmovngeq","cmovlq") .Case("cmovnge", "cmovl")
689 .Case("cmovnlw", "cmovgew").Case("cmovnll", "cmovgel")
690 .Case("cmovnlq", "cmovgeq").Case("cmovnl", "cmovge")
691 .Case("cmovnlew","cmovgw") .Case("cmovnlel","cmovgl")
692 .Case("cmovnleq","cmovgq") .Case("cmovnle", "cmovg")
693 .Case("cmovnzw", "cmovnew").Case("cmovnzl", "cmovnel")
694 .Case("cmovnzq", "cmovneq").Case("cmovnz", "cmovne")
695 .Case("cmovzw", "cmovew") .Case("cmovzl", "cmovel")
696 .Case("cmovzq", "cmoveq") .Case("cmovz", "cmove")
Chris Lattnerc2b942a2010-09-22 04:56:20 +0000697 // Floating point stack cmov aliases.
698 .Case("fcmovz", "fcmove")
699 .Case("fcmova", "fcmovnbe")
700 .Case("fcmovnae", "fcmovb")
701 .Case("fcmovna", "fcmovbe")
702 .Case("fcmovae", "fcmovnb")
Kevin Enderby5e394422010-05-28 20:59:10 +0000703 .Case("fwait", "wait")
Chris Lattner35aa94b2010-09-16 20:46:38 +0000704 .Case("movzx", "movzb") // FIXME: Not correct.
705 .Case("fildq", "fildll")
Kevin Enderby41e8cc72010-10-27 00:59:28 +0000706 .Case("fcompi", "fcomip")
707 .Case("fucompi", "fucomip")
Kevin Enderbyf4630ec2010-10-27 02:32:19 +0000708 .Case("fldcww", "fldcw")
709 .Case("fnstcww", "fnstcw")
710 .Case("fstcww", "fstcw")
711 .Case("fnstsww", "fnstsw")
712 .Case("fstsww", "fstsw")
713 .Case("verrw", "verr")
Kevin Enderbye4608902010-10-27 03:01:02 +0000714 .Case("ud2a", "ud2")
Daniel Dunbar1b6c0602010-02-10 21:19:28 +0000715 .Default(Name);
Daniel Dunbar39e2dd72010-05-25 19:49:32 +0000716
717 // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}.
718 const MCExpr *ExtraImmOp = 0;
Bruno Cardoso Lopes428256b2010-06-23 21:10:57 +0000719 if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) &&
Daniel Dunbar39e2dd72010-05-25 19:49:32 +0000720 (PatchedName.endswith("ss") || PatchedName.endswith("sd") ||
721 PatchedName.endswith("ps") || PatchedName.endswith("pd"))) {
Bruno Cardoso Lopes428256b2010-06-23 21:10:57 +0000722 bool IsVCMP = PatchedName.startswith("vcmp");
723 unsigned SSECCIdx = IsVCMP ? 4 : 3;
Daniel Dunbar39e2dd72010-05-25 19:49:32 +0000724 unsigned SSEComparisonCode = StringSwitch<unsigned>(
Bruno Cardoso Lopes428256b2010-06-23 21:10:57 +0000725 PatchedName.slice(SSECCIdx, PatchedName.size() - 2))
Bruno Cardoso Lopescc69e132010-07-07 22:24:03 +0000726 .Case("eq", 0)
727 .Case("lt", 1)
728 .Case("le", 2)
729 .Case("unord", 3)
730 .Case("neq", 4)
731 .Case("nlt", 5)
732 .Case("nle", 6)
733 .Case("ord", 7)
734 .Case("eq_uq", 8)
735 .Case("nge", 9)
736 .Case("ngt", 0x0A)
737 .Case("false", 0x0B)
738 .Case("neq_oq", 0x0C)
739 .Case("ge", 0x0D)
740 .Case("gt", 0x0E)
741 .Case("true", 0x0F)
742 .Case("eq_os", 0x10)
743 .Case("lt_oq", 0x11)
744 .Case("le_oq", 0x12)
745 .Case("unord_s", 0x13)
746 .Case("neq_us", 0x14)
747 .Case("nlt_uq", 0x15)
748 .Case("nle_uq", 0x16)
749 .Case("ord_s", 0x17)
750 .Case("eq_us", 0x18)
751 .Case("nge_uq", 0x19)
752 .Case("ngt_uq", 0x1A)
753 .Case("false_os", 0x1B)
754 .Case("neq_os", 0x1C)
755 .Case("ge_oq", 0x1D)
756 .Case("gt_oq", 0x1E)
757 .Case("true_us", 0x1F)
Daniel Dunbar39e2dd72010-05-25 19:49:32 +0000758 .Default(~0U);
759 if (SSEComparisonCode != ~0U) {
760 ExtraImmOp = MCConstantExpr::Create(SSEComparisonCode,
761 getParser().getContext());
762 if (PatchedName.endswith("ss")) {
Bruno Cardoso Lopes428256b2010-06-23 21:10:57 +0000763 PatchedName = IsVCMP ? "vcmpss" : "cmpss";
Daniel Dunbar39e2dd72010-05-25 19:49:32 +0000764 } else if (PatchedName.endswith("sd")) {
Bruno Cardoso Lopes428256b2010-06-23 21:10:57 +0000765 PatchedName = IsVCMP ? "vcmpsd" : "cmpsd";
Daniel Dunbar39e2dd72010-05-25 19:49:32 +0000766 } else if (PatchedName.endswith("ps")) {
Bruno Cardoso Lopes428256b2010-06-23 21:10:57 +0000767 PatchedName = IsVCMP ? "vcmpps" : "cmpps";
Daniel Dunbar39e2dd72010-05-25 19:49:32 +0000768 } else {
769 assert(PatchedName.endswith("pd") && "Unexpected mnemonic!");
Bruno Cardoso Lopes428256b2010-06-23 21:10:57 +0000770 PatchedName = IsVCMP ? "vcmppd" : "cmppd";
Daniel Dunbar39e2dd72010-05-25 19:49:32 +0000771 }
772 }
773 }
Bruno Cardoso Lopesf528d2b2010-07-23 18:41:12 +0000774
775 // FIXME: Hack to recognize vpclmul<src1_quadword, src2_quadword>dq
776 if (PatchedName.startswith("vpclmul")) {
777 unsigned CLMULQuadWordSelect = StringSwitch<unsigned>(
778 PatchedName.slice(7, PatchedName.size() - 2))
779 .Case("lqlq", 0x00) // src1[63:0], src2[63:0]
780 .Case("hqlq", 0x01) // src1[127:64], src2[63:0]
781 .Case("lqhq", 0x10) // src1[63:0], src2[127:64]
782 .Case("hqhq", 0x11) // src1[127:64], src2[127:64]
783 .Default(~0U);
784 if (CLMULQuadWordSelect != ~0U) {
785 ExtraImmOp = MCConstantExpr::Create(CLMULQuadWordSelect,
786 getParser().getContext());
787 assert(PatchedName.endswith("dq") && "Unexpected mnemonic!");
788 PatchedName = "vpclmulqdq";
789 }
790 }
Michael J. Spencerc0c8df32010-10-09 11:00:50 +0000791
Daniel Dunbar1b6c0602010-02-10 21:19:28 +0000792 Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000793
Daniel Dunbar39e2dd72010-05-25 19:49:32 +0000794 if (ExtraImmOp)
795 Operands.push_back(X86Operand::CreateImm(ExtraImmOp, NameLoc, NameLoc));
Michael J. Spencerc0c8df32010-10-09 11:00:50 +0000796
797
Chris Lattner2544f422010-09-08 05:17:37 +0000798 // Determine whether this is an instruction prefix.
799 bool isPrefix =
Michael J. Spencerc0c8df32010-10-09 11:00:50 +0000800 PatchedName == "lock" || PatchedName == "rep" ||
Chris Lattner2544f422010-09-08 05:17:37 +0000801 PatchedName == "repne";
Michael J. Spencerc0c8df32010-10-09 11:00:50 +0000802
803
Chris Lattner2544f422010-09-08 05:17:37 +0000804 // This does the actual operand parsing. Don't parse any more if we have a
805 // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we
806 // just want to parse the "lock" as the first instruction and the "incl" as
807 // the next one.
808 if (getLexer().isNot(AsmToken::EndOfStatement) && !isPrefix) {
Daniel Dunbar0db68f42009-08-11 05:00:25 +0000809
810 // Parse '*' modifier.
811 if (getLexer().is(AsmToken::Star)) {
Sean Callanan18b83232010-01-19 21:44:56 +0000812 SMLoc Loc = Parser.getTok().getLoc();
Chris Lattnerb4307b32010-01-15 19:28:38 +0000813 Operands.push_back(X86Operand::CreateToken("*", Loc));
Sean Callananb9a25b72010-01-19 20:27:46 +0000814 Parser.Lex(); // Eat the star.
Daniel Dunbar0db68f42009-08-11 05:00:25 +0000815 }
816
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000817 // Read the first operand.
Chris Lattner309264d2010-01-15 18:44:13 +0000818 if (X86Operand *Op = ParseOperand())
819 Operands.push_back(Op);
Chris Lattnercbf8a982010-09-11 16:18:25 +0000820 else {
821 Parser.EatToEndOfStatement();
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000822 return true;
Chris Lattnercbf8a982010-09-11 16:18:25 +0000823 }
Daniel Dunbar39e2dd72010-05-25 19:49:32 +0000824
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000825 while (getLexer().is(AsmToken::Comma)) {
Sean Callananb9a25b72010-01-19 20:27:46 +0000826 Parser.Lex(); // Eat the comma.
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000827
828 // Parse and remember the operand.
Chris Lattner309264d2010-01-15 18:44:13 +0000829 if (X86Operand *Op = ParseOperand())
830 Operands.push_back(Op);
Chris Lattnercbf8a982010-09-11 16:18:25 +0000831 else {
832 Parser.EatToEndOfStatement();
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000833 return true;
Chris Lattnercbf8a982010-09-11 16:18:25 +0000834 }
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000835 }
Michael J. Spencerc0c8df32010-10-09 11:00:50 +0000836
Chris Lattnercbf8a982010-09-11 16:18:25 +0000837 if (getLexer().isNot(AsmToken::EndOfStatement)) {
838 Parser.EatToEndOfStatement();
Chris Lattner2544f422010-09-08 05:17:37 +0000839 return TokError("unexpected token in argument list");
Chris Lattnercbf8a982010-09-11 16:18:25 +0000840 }
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000841 }
Michael J. Spencerc0c8df32010-10-09 11:00:50 +0000842
Chris Lattner2544f422010-09-08 05:17:37 +0000843 if (getLexer().is(AsmToken::EndOfStatement))
844 Parser.Lex(); // Consume the EndOfStatement
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000845
Chris Lattner508fc472010-10-05 21:09:45 +0000846 // Hack to allow 'movq <largeimm>, <reg>' as an alias for movabsq.
847 if ((Name == "movq" || Name == "mov") && Operands.size() == 3 &&
848 static_cast<X86Operand*>(Operands[2])->isReg() &&
849 static_cast<X86Operand*>(Operands[1])->isImm() &&
850 !static_cast<X86Operand*>(Operands[1])->isImmSExti64i32()) {
851 delete Operands[0];
852 Operands[0] = X86Operand::CreateToken("movabsq", NameLoc);
853 }
Michael J. Spencerc0c8df32010-10-09 11:00:50 +0000854
Chris Lattnere9e16a32010-09-15 04:33:27 +0000855 // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>. Canonicalize to
Chris Lattneree211d02010-09-11 16:32:12 +0000856 // "shift <op>".
Daniel Dunbard5e77052010-03-13 00:47:29 +0000857 if ((Name.startswith("shr") || Name.startswith("sar") ||
858 Name.startswith("shl")) &&
Chris Lattner47ab90b2010-09-06 18:32:06 +0000859 Operands.size() == 3) {
860 X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]);
861 if (Op1->isImm() && isa<MCConstantExpr>(Op1->getImm()) &&
862 cast<MCConstantExpr>(Op1->getImm())->getValue() == 1) {
863 delete Operands[1];
864 Operands.erase(Operands.begin() + 1);
865 }
Daniel Dunbarf2de13f2010-03-20 22:36:38 +0000866 }
Michael J. Spencerc0c8df32010-10-09 11:00:50 +0000867
Chris Lattnere9e16a32010-09-15 04:33:27 +0000868 // FIXME: Hack to handle recognize "rc[lr] <op>" -> "rcl $1, <op>".
869 if ((Name.startswith("rcl") || Name.startswith("rcr")) &&
870 Operands.size() == 2) {
871 const MCExpr *One = MCConstantExpr::Create(1, getParser().getContext());
872 Operands.push_back(X86Operand::CreateImm(One, NameLoc, NameLoc));
873 std::swap(Operands[1], Operands[2]);
874 }
Michael J. Spencerc0c8df32010-10-09 11:00:50 +0000875
Chris Lattnercfad5642010-09-15 04:37:18 +0000876 // FIXME: Hack to handle recognize "sh[lr]d op,op" -> "shld $1, op,op".
877 if ((Name.startswith("shld") || Name.startswith("shrd")) &&
878 Operands.size() == 3) {
879 const MCExpr *One = MCConstantExpr::Create(1, getParser().getContext());
880 Operands.insert(Operands.begin()+1,
881 X86Operand::CreateImm(One, NameLoc, NameLoc));
882 }
Michael J. Spencerc0c8df32010-10-09 11:00:50 +0000883
Daniel Dunbard5e77052010-03-13 00:47:29 +0000884
Chris Lattneree211d02010-09-11 16:32:12 +0000885 // FIXME: Hack to handle recognize "in[bwl] <op>". Canonicalize it to
886 // "inb <op>, %al".
887 if ((Name == "inb" || Name == "inw" || Name == "inl") &&
888 Operands.size() == 2) {
889 unsigned Reg;
890 if (Name[2] == 'b')
891 Reg = MatchRegisterName("al");
892 else if (Name[2] == 'w')
893 Reg = MatchRegisterName("ax");
894 else
895 Reg = MatchRegisterName("eax");
896 SMLoc Loc = Operands.back()->getEndLoc();
897 Operands.push_back(X86Operand::CreateReg(Reg, Loc, Loc));
898 }
Michael J. Spencerc0c8df32010-10-09 11:00:50 +0000899
Chris Lattneree211d02010-09-11 16:32:12 +0000900 // FIXME: Hack to handle recognize "out[bwl] <op>". Canonicalize it to
901 // "outb %al, <op>".
902 if ((Name == "outb" || Name == "outw" || Name == "outl") &&
903 Operands.size() == 2) {
904 unsigned Reg;
905 if (Name[3] == 'b')
906 Reg = MatchRegisterName("al");
907 else if (Name[3] == 'w')
908 Reg = MatchRegisterName("ax");
909 else
910 Reg = MatchRegisterName("eax");
911 SMLoc Loc = Operands.back()->getEndLoc();
912 Operands.push_back(X86Operand::CreateReg(Reg, Loc, Loc));
913 std::swap(Operands[1], Operands[2]);
914 }
Michael J. Spencerc0c8df32010-10-09 11:00:50 +0000915
Chris Lattneref63c9a2010-09-14 23:34:29 +0000916 // FIXME: Hack to handle "out[bwl]? %al, (%dx)" -> "outb %al, %dx".
917 if ((Name == "outb" || Name == "outw" || Name == "outl" || Name == "out") &&
918 Operands.size() == 3) {
919 X86Operand &Op = *(X86Operand*)Operands.back();
920 if (Op.isMem() && Op.Mem.SegReg == 0 &&
921 isa<MCConstantExpr>(Op.Mem.Disp) &&
922 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
923 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
924 SMLoc Loc = Op.getEndLoc();
925 Operands.back() = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
926 delete &Op;
927 }
928 }
Michael J. Spencerc0c8df32010-10-09 11:00:50 +0000929
Kevin Enderbycf50a532010-05-25 20:52:34 +0000930 // FIXME: Hack to handle "f{mul*,add*,sub*,div*} $op, st(0)" the same as
931 // "f{mul*,add*,sub*,div*} $op"
932 if ((Name.startswith("fmul") || Name.startswith("fadd") ||
933 Name.startswith("fsub") || Name.startswith("fdiv")) &&
934 Operands.size() == 3 &&
935 static_cast<X86Operand*>(Operands[2])->isReg() &&
936 static_cast<X86Operand*>(Operands[2])->getReg() == X86::ST0) {
937 delete Operands[2];
938 Operands.erase(Operands.begin() + 2);
939 }
Michael J. Spencerc0c8df32010-10-09 11:00:50 +0000940
Chris Lattnercb296ec2010-09-27 07:08:21 +0000941 // FIXME: Hack to handle "f{mulp,addp} st(0), $op" the same as
Chris Lattnera25f9332010-09-29 18:39:16 +0000942 // "f{mulp,addp} $op", since they commute. We also allow fdivrp/fsubrp even
943 // though they don't commute, solely because gas does support this.
944 if ((Name=="fmulp" || Name=="faddp" || Name=="fsubrp" || Name=="fdivrp") &&
945 Operands.size() == 3 &&
Chris Lattner2c5291b2010-09-22 06:26:39 +0000946 static_cast<X86Operand*>(Operands[1])->isReg() &&
947 static_cast<X86Operand*>(Operands[1])->getReg() == X86::ST0) {
948 delete Operands[1];
949 Operands.erase(Operands.begin() + 1);
950 }
Michael J. Spencerc0c8df32010-10-09 11:00:50 +0000951
Daniel Dunbarfba88d42010-08-24 19:37:56 +0000952 // FIXME: Hack to handle "imul <imm>, B" which is an alias for "imul <imm>, B,
953 // B".
Daniel Dunbarae528f62010-08-24 19:24:18 +0000954 if (Name.startswith("imul") && Operands.size() == 3 &&
Daniel Dunbarfba88d42010-08-24 19:37:56 +0000955 static_cast<X86Operand*>(Operands[1])->isImm() &&
Daniel Dunbarae528f62010-08-24 19:24:18 +0000956 static_cast<X86Operand*>(Operands.back())->isReg()) {
957 X86Operand *Op = static_cast<X86Operand*>(Operands.back());
958 Operands.push_back(X86Operand::CreateReg(Op->getReg(), Op->getStartLoc(),
959 Op->getEndLoc()));
960 }
Michael J. Spencerc0c8df32010-10-09 11:00:50 +0000961
Chris Lattnerc5cebeb2010-09-06 23:51:44 +0000962 // 'sldt <mem>' can be encoded with either sldtw or sldtq with the same
963 // effect (both store to a 16-bit mem). Force to sldtw to avoid ambiguity
964 // errors, since its encoding is the most compact.
965 if (Name == "sldt" && Operands.size() == 2 &&
Benjamin Krameraceeb3a2010-09-07 14:40:58 +0000966 static_cast<X86Operand*>(Operands[1])->isMem()) {
967 delete Operands[0];
Chris Lattnerc5cebeb2010-09-06 23:51:44 +0000968 Operands[0] = X86Operand::CreateToken("sldtw", NameLoc);
Benjamin Krameraceeb3a2010-09-07 14:40:58 +0000969 }
Michael J. Spencerc0c8df32010-10-09 11:00:50 +0000970
Chris Lattner9607c402010-09-08 04:53:27 +0000971 // The assembler accepts "xchgX <reg>, <mem>" and "xchgX <mem>, <reg>" as
972 // synonyms. Our tables only have the "<reg>, <mem>" form, so if we see the
973 // other operand order, swap them.
Chris Lattner90b54542010-09-08 22:27:05 +0000974 if (Name == "xchgb" || Name == "xchgw" || Name == "xchgl" || Name == "xchgq"||
975 Name == "xchg")
Chris Lattner9607c402010-09-08 04:53:27 +0000976 if (Operands.size() == 3 &&
977 static_cast<X86Operand*>(Operands[1])->isMem() &&
978 static_cast<X86Operand*>(Operands[2])->isReg()) {
979 std::swap(Operands[1], Operands[2]);
980 }
Daniel Dunbarae528f62010-08-24 19:24:18 +0000981
Chris Lattnerc8ae35a2010-09-08 05:51:12 +0000982 // The assembler accepts "testX <reg>, <mem>" and "testX <mem>, <reg>" as
983 // synonyms. Our tables only have the "<mem>, <reg>" form, so if we see the
984 // other operand order, swap them.
Chris Lattner90b54542010-09-08 22:27:05 +0000985 if (Name == "testb" || Name == "testw" || Name == "testl" || Name == "testq"||
986 Name == "test")
Chris Lattnerc8ae35a2010-09-08 05:51:12 +0000987 if (Operands.size() == 3 &&
988 static_cast<X86Operand*>(Operands[1])->isReg() &&
989 static_cast<X86Operand*>(Operands[2])->isMem()) {
990 std::swap(Operands[1], Operands[2]);
991 }
Michael J. Spencerc0c8df32010-10-09 11:00:50 +0000992
Chris Lattner2d592d12010-09-15 04:04:33 +0000993 // The assembler accepts these instructions with no operand as a synonym for
994 // an instruction acting on st(1). e.g. "fxch" -> "fxch %st(1)".
995 if ((Name == "fxch" || Name == "fucom" || Name == "fucomp" ||
Michael J. Spencerc0c8df32010-10-09 11:00:50 +0000996 Name == "faddp" || Name == "fsubp" || Name == "fsubrp" ||
Chris Lattner2d592d12010-09-15 04:04:33 +0000997 Name == "fmulp" || Name == "fdivp" || Name == "fdivrp") &&
998 Operands.size() == 1) {
999 Operands.push_back(X86Operand::CreateReg(MatchRegisterName("st(1)"),
1000 NameLoc, NameLoc));
1001 }
Michael J. Spencerc0c8df32010-10-09 11:00:50 +00001002
Kevin Enderby41e8cc72010-10-27 00:59:28 +00001003 // The assembler accepts this instruction with no operand as a synonym for an
1004 // instruction taking %st(1),%st(0). e.g. "fcompi" -> "fcompi %st(1),st(0)".
1005 if (Name == "fcompi" && Operands.size() == 1) {
1006 Operands.push_back(X86Operand::CreateReg(MatchRegisterName("st(1)"),
1007 NameLoc, NameLoc));
1008 Operands.push_back(X86Operand::CreateReg(MatchRegisterName("st(0)"),
1009 NameLoc, NameLoc));
1010 }
1011
Chris Lattner8f777a22010-09-15 04:08:38 +00001012 // The assembler accepts these instructions with two few operands as a synonym
1013 // for taking %st(1),%st(0) or X, %st(0).
Kevin Enderby41e8cc72010-10-27 00:59:28 +00001014 if ((Name == "fcomi" || Name == "fucomi" || Name == "fucompi" ||
1015 Name == "fcompi" ) &&
1016 Operands.size() < 3) {
Chris Lattner8f777a22010-09-15 04:08:38 +00001017 if (Operands.size() == 1)
1018 Operands.push_back(X86Operand::CreateReg(MatchRegisterName("st(1)"),
1019 NameLoc, NameLoc));
1020 Operands.push_back(X86Operand::CreateReg(MatchRegisterName("st(0)"),
1021 NameLoc, NameLoc));
1022 }
Michael J. Spencerc0c8df32010-10-09 11:00:50 +00001023
Chris Lattner84f362d2010-09-15 04:15:16 +00001024 // The assembler accepts various amounts of brokenness for fnstsw.
1025 if (Name == "fnstsw") {
1026 if (Operands.size() == 2 &&
1027 static_cast<X86Operand*>(Operands[1])->isReg()) {
1028 // "fnstsw al" and "fnstsw eax" -> "fnstw"
1029 unsigned Reg = static_cast<X86Operand*>(Operands[1])->Reg.RegNo;
1030 if (Reg == MatchRegisterName("eax") ||
1031 Reg == MatchRegisterName("al")) {
1032 delete Operands[1];
1033 Operands.pop_back();
1034 }
1035 }
1036
1037 // "fnstw" -> "fnstw %ax"
1038 if (Operands.size() == 1)
1039 Operands.push_back(X86Operand::CreateReg(MatchRegisterName("ax"),
1040 NameLoc, NameLoc));
1041 }
Michael J. Spencerc0c8df32010-10-09 11:00:50 +00001042
Chris Lattnercbb44262010-09-15 05:25:21 +00001043 // jmp $42,$5 -> ljmp, similarly for call.
1044 if ((Name.startswith("call") || Name.startswith("jmp")) &&
1045 Operands.size() == 3 &&
1046 static_cast<X86Operand*>(Operands[1])->isImm() &&
1047 static_cast<X86Operand*>(Operands[2])->isImm()) {
1048 const char *NewOpName = StringSwitch<const char *>(Name)
1049 .Case("jmp", "ljmp")
1050 .Case("jmpw", "ljmpw")
1051 .Case("jmpl", "ljmpl")
1052 .Case("jmpq", "ljmpq")
1053 .Case("call", "lcall")
1054 .Case("callw", "lcallw")
1055 .Case("calll", "lcalll")
1056 .Case("callq", "lcallq")
1057 .Default(0);
1058 if (NewOpName) {
1059 delete Operands[0];
1060 Operands[0] = X86Operand::CreateToken(NewOpName, NameLoc);
Chris Lattnerd0bcc9a2010-09-15 05:30:20 +00001061 Name = NewOpName;
Chris Lattnercbb44262010-09-15 05:25:21 +00001062 }
1063 }
Michael J. Spencerc0c8df32010-10-09 11:00:50 +00001064
Chris Lattnerd0bcc9a2010-09-15 05:30:20 +00001065 // lcall and ljmp -> lcalll and ljmpl
1066 if ((Name == "lcall" || Name == "ljmp") && Operands.size() == 3) {
1067 delete Operands[0];
1068 Operands[0] = X86Operand::CreateToken(Name == "lcall" ? "lcalll" : "ljmpl",
1069 NameLoc);
1070 }
Michael J. Spencerc0c8df32010-10-09 11:00:50 +00001071
Chris Lattner1eb1b682010-09-22 05:49:14 +00001072 // call foo is not ambiguous with callw.
1073 if (Name == "call" && Operands.size() == 2) {
1074 const char *NewName = Is64Bit ? "callq" : "calll";
1075 delete Operands[0];
1076 Operands[0] = X86Operand::CreateToken(NewName, NameLoc);
1077 Name = NewName;
1078 }
Michael J. Spencerc0c8df32010-10-09 11:00:50 +00001079
Chris Lattner61129252010-09-22 03:50:32 +00001080 // movsd -> movsl (when no operands are specified).
1081 if (Name == "movsd" && Operands.size() == 1) {
1082 delete Operands[0];
1083 Operands[0] = X86Operand::CreateToken("movsl", NameLoc);
1084 }
Michael J. Spencerc0c8df32010-10-09 11:00:50 +00001085
Chris Lattner0c289c12010-09-22 04:04:03 +00001086 // fstp <mem> -> fstps <mem>. Without this, we'll default to fstpl due to
1087 // suffix searching.
1088 if (Name == "fstp" && Operands.size() == 2 &&
1089 static_cast<X86Operand*>(Operands[1])->isMem()) {
1090 delete Operands[0];
1091 Operands[0] = X86Operand::CreateToken("fstps", NameLoc);
1092 }
Michael J. Spencerc0c8df32010-10-09 11:00:50 +00001093
1094
Chris Lattnerfd8fddd2010-09-27 04:23:03 +00001095 // "clr <reg>" -> "xor <reg>, <reg>".
1096 if ((Name == "clrb" || Name == "clrw" || Name == "clrl" || Name == "clrq" ||
1097 Name == "clr") && Operands.size() == 2 &&
1098 static_cast<X86Operand*>(Operands[1])->isReg()) {
1099 unsigned RegNo = static_cast<X86Operand*>(Operands[1])->getReg();
1100 Operands.push_back(X86Operand::CreateReg(RegNo, NameLoc, NameLoc));
1101 delete Operands[0];
1102 Operands[0] = X86Operand::CreateToken("xor", NameLoc);
1103 }
Michael J. Spencerc0c8df32010-10-09 11:00:50 +00001104
Kevin Enderby7aef62f2010-10-18 17:04:36 +00001105 // FIXME: Hack to handle recognize "aa[dm]" -> "aa[dm] $0xA".
1106 if ((Name.startswith("aad") || Name.startswith("aam")) &&
1107 Operands.size() == 1) {
1108 const MCExpr *A = MCConstantExpr::Create(0xA, getParser().getContext());
1109 Operands.push_back(X86Operand::CreateImm(A, NameLoc, NameLoc));
1110 }
1111
Kevin Enderby87f4a1a2010-10-19 00:01:44 +00001112 // "lgdtl" is not ambiguous 32-bit mode and is the same as "lgdt".
1113 // "lgdtq" is not ambiguous 64-bit mode and is the same as "lgdt".
1114 if ((Name == "lgdtl" && Is64Bit == false) ||
1115 (Name == "lgdtq" && Is64Bit == true)) {
1116 const char *NewName = "lgdt";
1117 delete Operands[0];
1118 Operands[0] = X86Operand::CreateToken(NewName, NameLoc);
1119 Name = NewName;
1120 }
1121
1122 // "lidtl" is not ambiguous 32-bit mode and is the same as "lidt".
1123 // "lidtq" is not ambiguous 64-bit mode and is the same as "lidt".
1124 if ((Name == "lidtl" && Is64Bit == false) ||
1125 (Name == "lidtq" && Is64Bit == true)) {
1126 const char *NewName = "lidt";
1127 delete Operands[0];
1128 Operands[0] = X86Operand::CreateToken(NewName, NameLoc);
1129 Name = NewName;
1130 }
1131
1132 // "sgdtl" is not ambiguous 32-bit mode and is the same as "sgdt".
1133 // "sgdtq" is not ambiguous 64-bit mode and is the same as "sgdt".
1134 if ((Name == "sgdtl" && Is64Bit == false) ||
1135 (Name == "sgdtq" && Is64Bit == true)) {
1136 const char *NewName = "sgdt";
1137 delete Operands[0];
1138 Operands[0] = X86Operand::CreateToken(NewName, NameLoc);
1139 Name = NewName;
1140 }
1141
1142 // "sidtl" is not ambiguous 32-bit mode and is the same as "sidt".
1143 // "sidtq" is not ambiguous 64-bit mode and is the same as "sidt".
1144 if ((Name == "sidtl" && Is64Bit == false) ||
1145 (Name == "sidtq" && Is64Bit == true)) {
1146 const char *NewName = "sidt";
1147 delete Operands[0];
1148 Operands[0] = X86Operand::CreateToken(NewName, NameLoc);
1149 Name = NewName;
1150 }
1151
Chris Lattner98986712010-01-14 22:21:20 +00001152 return false;
Daniel Dunbara3af3702009-07-20 18:55:04 +00001153}
1154
Kevin Enderby9c656452009-09-10 20:51:44 +00001155bool X86ATTAsmParser::ParseDirective(AsmToken DirectiveID) {
1156 StringRef IDVal = DirectiveID.getIdentifier();
1157 if (IDVal == ".word")
1158 return ParseDirectiveWord(2, DirectiveID.getLoc());
1159 return true;
1160}
1161
1162/// ParseDirectiveWord
1163/// ::= .word [ expression (, expression)* ]
1164bool X86ATTAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
1165 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1166 for (;;) {
1167 const MCExpr *Value;
1168 if (getParser().ParseExpression(Value))
1169 return true;
1170
Chris Lattneraaec2052010-01-19 19:46:13 +00001171 getParser().getStreamer().EmitValue(Value, Size, 0 /*addrspace*/);
Kevin Enderby9c656452009-09-10 20:51:44 +00001172
1173 if (getLexer().is(AsmToken::EndOfStatement))
1174 break;
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +00001175
Kevin Enderby9c656452009-09-10 20:51:44 +00001176 // FIXME: Improve diagnostic.
1177 if (getLexer().isNot(AsmToken::Comma))
1178 return Error(L, "unexpected token in directive");
Sean Callananb9a25b72010-01-19 20:27:46 +00001179 Parser.Lex();
Kevin Enderby9c656452009-09-10 20:51:44 +00001180 }
1181 }
1182
Sean Callananb9a25b72010-01-19 20:27:46 +00001183 Parser.Lex();
Kevin Enderby9c656452009-09-10 20:51:44 +00001184 return false;
1185}
1186
Daniel Dunbarf1e29d42010-08-12 00:55:38 +00001187
Chris Lattner2d592d12010-09-15 04:04:33 +00001188bool X86ATTAsmParser::
Chris Lattner7036f8b2010-09-29 01:42:58 +00001189MatchAndEmitInstruction(SMLoc IDLoc,
Chris Lattner7c51a312010-09-29 01:50:45 +00001190 SmallVectorImpl<MCParsedAsmOperand*> &Operands,
Chris Lattner7036f8b2010-09-29 01:42:58 +00001191 MCStreamer &Out) {
Daniel Dunbarf1e29d42010-08-12 00:55:38 +00001192 assert(!Operands.empty() && "Unexpect empty operand list!");
Chris Lattner7c51a312010-09-29 01:50:45 +00001193 X86Operand *Op = static_cast<X86Operand*>(Operands[0]);
1194 assert(Op->isToken() && "Leading operand should always be a mnemonic!");
Daniel Dunbarf1e29d42010-08-12 00:55:38 +00001195
Chris Lattner7c51a312010-09-29 01:50:45 +00001196 // First, handle aliases that expand to multiple instructions.
1197 // FIXME: This should be replaced with a real .td file alias mechanism.
Andrew Trick0966ec02010-10-22 03:58:29 +00001198 if (Op->getToken() == "fstsw" || Op->getToken() == "fstcw" ||
Chris Lattner905f2e02010-09-30 17:11:29 +00001199 Op->getToken() == "finit" || Op->getToken() == "fsave" ||
Kevin Enderby5a378072010-10-27 02:53:04 +00001200 Op->getToken() == "fstenv" || Op->getToken() == "fclex") {
Chris Lattner7c51a312010-09-29 01:50:45 +00001201 MCInst Inst;
1202 Inst.setOpcode(X86::WAIT);
1203 Out.EmitInstruction(Inst);
1204
Chris Lattner0bb83a82010-09-30 16:39:29 +00001205 const char *Repl =
1206 StringSwitch<const char*>(Op->getToken())
Chris Lattner9ee4aed2010-09-30 16:42:53 +00001207 .Case("finit", "fninit")
Chris Lattner905f2e02010-09-30 17:11:29 +00001208 .Case("fsave", "fnsave")
1209 .Case("fstcw", "fnstcw")
1210 .Case("fstenv", "fnstenv")
1211 .Case("fstsw", "fnstsw")
Kevin Enderby5a378072010-10-27 02:53:04 +00001212 .Case("fclex", "fnclex")
Chris Lattner0bb83a82010-09-30 16:39:29 +00001213 .Default(0);
1214 assert(Repl && "Unknown wait-prefixed instruction");
Benjamin Kramerb0f96fa2010-10-01 12:25:27 +00001215 delete Operands[0];
Chris Lattner0bb83a82010-09-30 16:39:29 +00001216 Operands[0] = X86Operand::CreateToken(Repl, IDLoc);
Chris Lattner7c51a312010-09-29 01:50:45 +00001217 }
Michael J. Spencerc0c8df32010-10-09 11:00:50 +00001218
Chris Lattnera008e8a2010-09-06 21:54:15 +00001219 bool WasOriginallyInvalidOperand = false;
Chris Lattnerce4a3352010-09-06 22:11:18 +00001220 unsigned OrigErrorInfo;
Chris Lattner7036f8b2010-09-29 01:42:58 +00001221 MCInst Inst;
Michael J. Spencerc0c8df32010-10-09 11:00:50 +00001222
Daniel Dunbarc918d602010-05-04 16:12:42 +00001223 // First, try a direct match.
Chris Lattnerce4a3352010-09-06 22:11:18 +00001224 switch (MatchInstructionImpl(Operands, Inst, OrigErrorInfo)) {
Chris Lattnerec6789f2010-09-06 20:08:02 +00001225 case Match_Success:
Chris Lattner7036f8b2010-09-29 01:42:58 +00001226 Out.EmitInstruction(Inst);
Daniel Dunbarc918d602010-05-04 16:12:42 +00001227 return false;
Chris Lattnerec6789f2010-09-06 20:08:02 +00001228 case Match_MissingFeature:
1229 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1230 return true;
Chris Lattnera008e8a2010-09-06 21:54:15 +00001231 case Match_InvalidOperand:
1232 WasOriginallyInvalidOperand = true;
1233 break;
1234 case Match_MnemonicFail:
Chris Lattnerec6789f2010-09-06 20:08:02 +00001235 break;
1236 }
Daniel Dunbarc918d602010-05-04 16:12:42 +00001237
Daniel Dunbarc918d602010-05-04 16:12:42 +00001238 // FIXME: Ideally, we would only attempt suffix matches for things which are
1239 // valid prefixes, and we could just infer the right unambiguous
1240 // type. However, that requires substantially more matcher support than the
1241 // following hack.
Michael J. Spencerc0c8df32010-10-09 11:00:50 +00001242
Daniel Dunbarc918d602010-05-04 16:12:42 +00001243 // Change the operand to point to a temporary token.
Daniel Dunbarc918d602010-05-04 16:12:42 +00001244 StringRef Base = Op->getToken();
Daniel Dunbarf1e29d42010-08-12 00:55:38 +00001245 SmallString<16> Tmp;
1246 Tmp += Base;
1247 Tmp += ' ';
1248 Op->setTokenValue(Tmp.str());
Daniel Dunbarc918d602010-05-04 16:12:42 +00001249
1250 // Check for the various suffix matches.
1251 Tmp[Base.size()] = 'b';
Chris Lattnerce4a3352010-09-06 22:11:18 +00001252 unsigned BErrorInfo, WErrorInfo, LErrorInfo, QErrorInfo;
1253 MatchResultTy MatchB = MatchInstructionImpl(Operands, Inst, BErrorInfo);
Daniel Dunbarc918d602010-05-04 16:12:42 +00001254 Tmp[Base.size()] = 'w';
Chris Lattnerce4a3352010-09-06 22:11:18 +00001255 MatchResultTy MatchW = MatchInstructionImpl(Operands, Inst, WErrorInfo);
Daniel Dunbarc918d602010-05-04 16:12:42 +00001256 Tmp[Base.size()] = 'l';
Chris Lattnerce4a3352010-09-06 22:11:18 +00001257 MatchResultTy MatchL = MatchInstructionImpl(Operands, Inst, LErrorInfo);
Daniel Dunbar04814492010-05-12 00:54:20 +00001258 Tmp[Base.size()] = 'q';
Chris Lattnerce4a3352010-09-06 22:11:18 +00001259 MatchResultTy MatchQ = MatchInstructionImpl(Operands, Inst, QErrorInfo);
Daniel Dunbarc918d602010-05-04 16:12:42 +00001260
1261 // Restore the old token.
1262 Op->setTokenValue(Base);
1263
1264 // If exactly one matched, then we treat that as a successful match (and the
1265 // instruction will already have been filled in correctly, since the failing
1266 // matches won't have modified it).
Chris Lattnerec6789f2010-09-06 20:08:02 +00001267 unsigned NumSuccessfulMatches =
1268 (MatchB == Match_Success) + (MatchW == Match_Success) +
1269 (MatchL == Match_Success) + (MatchQ == Match_Success);
Chris Lattner7036f8b2010-09-29 01:42:58 +00001270 if (NumSuccessfulMatches == 1) {
1271 Out.EmitInstruction(Inst);
Daniel Dunbarc918d602010-05-04 16:12:42 +00001272 return false;
Chris Lattner7036f8b2010-09-29 01:42:58 +00001273 }
Daniel Dunbarc918d602010-05-04 16:12:42 +00001274
Chris Lattnerec6789f2010-09-06 20:08:02 +00001275 // Otherwise, the match failed, try to produce a decent error message.
Daniel Dunbarf1e29d42010-08-12 00:55:38 +00001276
Daniel Dunbar09062b12010-08-12 00:55:42 +00001277 // If we had multiple suffix matches, then identify this as an ambiguous
1278 // match.
Chris Lattnerec6789f2010-09-06 20:08:02 +00001279 if (NumSuccessfulMatches > 1) {
Daniel Dunbar09062b12010-08-12 00:55:42 +00001280 char MatchChars[4];
1281 unsigned NumMatches = 0;
Chris Lattnerec6789f2010-09-06 20:08:02 +00001282 if (MatchB == Match_Success)
Daniel Dunbar09062b12010-08-12 00:55:42 +00001283 MatchChars[NumMatches++] = 'b';
Chris Lattnerec6789f2010-09-06 20:08:02 +00001284 if (MatchW == Match_Success)
Daniel Dunbar09062b12010-08-12 00:55:42 +00001285 MatchChars[NumMatches++] = 'w';
Chris Lattnerec6789f2010-09-06 20:08:02 +00001286 if (MatchL == Match_Success)
Daniel Dunbar09062b12010-08-12 00:55:42 +00001287 MatchChars[NumMatches++] = 'l';
Chris Lattnerec6789f2010-09-06 20:08:02 +00001288 if (MatchQ == Match_Success)
Daniel Dunbar09062b12010-08-12 00:55:42 +00001289 MatchChars[NumMatches++] = 'q';
1290
1291 SmallString<126> Msg;
1292 raw_svector_ostream OS(Msg);
1293 OS << "ambiguous instructions require an explicit suffix (could be ";
1294 for (unsigned i = 0; i != NumMatches; ++i) {
1295 if (i != 0)
1296 OS << ", ";
1297 if (i + 1 == NumMatches)
1298 OS << "or ";
1299 OS << "'" << Base << MatchChars[i] << "'";
1300 }
1301 OS << ")";
1302 Error(IDLoc, OS.str());
Chris Lattnerec6789f2010-09-06 20:08:02 +00001303 return true;
Daniel Dunbar09062b12010-08-12 00:55:42 +00001304 }
Michael J. Spencerc0c8df32010-10-09 11:00:50 +00001305
Chris Lattnera008e8a2010-09-06 21:54:15 +00001306 // Okay, we know that none of the variants matched successfully.
Michael J. Spencerc0c8df32010-10-09 11:00:50 +00001307
Chris Lattnera008e8a2010-09-06 21:54:15 +00001308 // If all of the instructions reported an invalid mnemonic, then the original
1309 // mnemonic was invalid.
1310 if ((MatchB == Match_MnemonicFail) && (MatchW == Match_MnemonicFail) &&
1311 (MatchL == Match_MnemonicFail) && (MatchQ == Match_MnemonicFail)) {
Chris Lattnerce4a3352010-09-06 22:11:18 +00001312 if (!WasOriginallyInvalidOperand) {
Michael J. Spencerc0c8df32010-10-09 11:00:50 +00001313 Error(IDLoc, "invalid instruction mnemonic '" + Base + "'");
Chris Lattnerce4a3352010-09-06 22:11:18 +00001314 return true;
1315 }
1316
1317 // Recover location info for the operand if we know which was the problem.
1318 SMLoc ErrorLoc = IDLoc;
1319 if (OrigErrorInfo != ~0U) {
Chris Lattnerf8840122010-09-15 03:50:11 +00001320 if (OrigErrorInfo >= Operands.size())
1321 return Error(IDLoc, "too few operands for instruction");
Michael J. Spencerc0c8df32010-10-09 11:00:50 +00001322
Chris Lattnerce4a3352010-09-06 22:11:18 +00001323 ErrorLoc = ((X86Operand*)Operands[OrigErrorInfo])->getStartLoc();
1324 if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
1325 }
1326
Chris Lattnerf8840122010-09-15 03:50:11 +00001327 return Error(ErrorLoc, "invalid operand for instruction");
Chris Lattnera008e8a2010-09-06 21:54:15 +00001328 }
Michael J. Spencerc0c8df32010-10-09 11:00:50 +00001329
Chris Lattnerec6789f2010-09-06 20:08:02 +00001330 // If one instruction matched with a missing feature, report this as a
1331 // missing feature.
1332 if ((MatchB == Match_MissingFeature) + (MatchW == Match_MissingFeature) +
Chris Lattnera008e8a2010-09-06 21:54:15 +00001333 (MatchL == Match_MissingFeature) + (MatchQ == Match_MissingFeature) == 1){
Chris Lattnerec6789f2010-09-06 20:08:02 +00001334 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1335 return true;
1336 }
Michael J. Spencerc0c8df32010-10-09 11:00:50 +00001337
Chris Lattnera008e8a2010-09-06 21:54:15 +00001338 // If one instruction matched with an invalid operand, report this as an
1339 // operand failure.
1340 if ((MatchB == Match_InvalidOperand) + (MatchW == Match_InvalidOperand) +
1341 (MatchL == Match_InvalidOperand) + (MatchQ == Match_InvalidOperand) == 1){
1342 Error(IDLoc, "invalid operand for instruction");
1343 return true;
1344 }
Michael J. Spencerc0c8df32010-10-09 11:00:50 +00001345
Chris Lattnerec6789f2010-09-06 20:08:02 +00001346 // If all of these were an outright failure, report it in a useless way.
1347 // FIXME: We should give nicer diagnostics about the exact failure.
Chris Lattnera008e8a2010-09-06 21:54:15 +00001348 Error(IDLoc, "unknown use of instruction mnemonic without a size suffix");
Daniel Dunbarc918d602010-05-04 16:12:42 +00001349 return true;
1350}
1351
1352
Sean Callanane88f5522010-01-23 02:43:15 +00001353extern "C" void LLVMInitializeX86AsmLexer();
1354
Daniel Dunbar092a9dd2009-07-17 20:42:00 +00001355// Force static initialization.
1356extern "C" void LLVMInitializeX86AsmParser() {
Daniel Dunbarf98bc632010-03-18 20:06:02 +00001357 RegisterAsmParser<X86_32ATTAsmParser> X(TheX86_32Target);
1358 RegisterAsmParser<X86_64ATTAsmParser> Y(TheX86_64Target);
Sean Callanane88f5522010-01-23 02:43:15 +00001359 LLVMInitializeX86AsmLexer();
Daniel Dunbar092a9dd2009-07-17 20:42:00 +00001360}
Daniel Dunbar0e2771f2009-07-29 00:02:19 +00001361
Chris Lattner0692ee62010-09-06 19:11:01 +00001362#define GET_REGISTER_MATCHER
1363#define GET_MATCHER_IMPLEMENTATION
Daniel Dunbar0e2771f2009-07-29 00:02:19 +00001364#include "X86GenAsmMatcher.inc"