blob: a6b2b77a4acfea1e1c075e7c347ee725c736f7c9 [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"
Daniel Dunbarf1e29d42010-08-12 00:55:38 +000013#include "llvm/ADT/SmallString.h"
Daniel Dunbardbd692a2009-07-20 20:01:54 +000014#include "llvm/ADT/SmallVector.h"
Daniel Dunbar1b6c0602010-02-10 21:19:28 +000015#include "llvm/ADT/StringSwitch.h"
Daniel Dunbar16cdcb32009-07-28 22:40:46 +000016#include "llvm/ADT/Twine.h"
Kevin Enderby9c656452009-09-10 20:51:44 +000017#include "llvm/MC/MCStreamer.h"
Daniel Dunbar8c2eebe2009-08-31 08:08:38 +000018#include "llvm/MC/MCExpr.h"
Daniel Dunbara027d222009-07-31 02:32:59 +000019#include "llvm/MC/MCInst.h"
Chris Lattnerc6ef2772010-01-22 01:44:57 +000020#include "llvm/MC/MCParser/MCAsmLexer.h"
21#include "llvm/MC/MCParser/MCAsmParser.h"
22#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
Daniel Dunbar16cdcb32009-07-28 22:40:46 +000023#include "llvm/Support/SourceMgr.h"
Daniel Dunbar09062b12010-08-12 00:55:42 +000024#include "llvm/Support/raw_ostream.h"
Daniel Dunbar092a9dd2009-07-17 20:42:00 +000025#include "llvm/Target/TargetRegistry.h"
26#include "llvm/Target/TargetAsmParser.h"
27using namespace llvm;
28
29namespace {
Benjamin Kramerc6b79ac2009-07-31 11:35:26 +000030struct X86Operand;
Daniel Dunbar16cdcb32009-07-28 22:40:46 +000031
32class X86ATTAsmParser : public TargetAsmParser {
33 MCAsmParser &Parser;
Daniel Dunbard73ada72010-07-19 00:33:49 +000034 TargetMachine &TM;
Daniel Dunbar16cdcb32009-07-28 22:40:46 +000035
Daniel Dunbarf98bc632010-03-18 20:06:02 +000036protected:
37 unsigned Is64Bit : 1;
38
Daniel Dunbar16cdcb32009-07-28 22:40:46 +000039private:
Daniel Dunbar16cdcb32009-07-28 22:40:46 +000040 MCAsmParser &getParser() const { return Parser; }
41
42 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
43
Daniel Dunbar16cdcb32009-07-28 22:40:46 +000044 bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
45
Chris Lattner29ef9a22010-01-15 18:51:29 +000046 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
Daniel Dunbar16cdcb32009-07-28 22:40:46 +000047
Chris Lattner309264d2010-01-15 18:44:13 +000048 X86Operand *ParseOperand();
Chris Lattnereef6d782010-04-17 18:56:34 +000049 X86Operand *ParseMemOperand(unsigned SegReg, SMLoc StartLoc);
Kevin Enderby9c656452009-09-10 20:51:44 +000050
51 bool ParseDirectiveWord(unsigned Size, SMLoc L);
52
Daniel Dunbarf1e29d42010-08-12 00:55:38 +000053 bool MatchInstruction(SMLoc IDLoc,
54 const SmallVectorImpl<MCParsedAsmOperand*> &Operands,
Daniel Dunbar20927f22009-08-07 08:26:05 +000055 MCInst &Inst);
56
Daniel Dunbar54074b52010-07-19 05:44:09 +000057 /// @name Auto-generated Matcher Functions
58 /// {
Chris Lattner0692ee62010-09-06 19:11:01 +000059
60#define GET_ASSEMBLER_HEADER
61#include "X86GenAsmMatcher.inc"
62
Daniel Dunbar0e2771f2009-07-29 00:02:19 +000063 /// }
Daniel Dunbar16cdcb32009-07-28 22:40:46 +000064
65public:
Daniel Dunbard73ada72010-07-19 00:33:49 +000066 X86ATTAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &TM)
Daniel Dunbar54074b52010-07-19 05:44:09 +000067 : TargetAsmParser(T), Parser(_Parser), TM(TM) {
68
69 // Initialize the set of available features.
70 setAvailableFeatures(ComputeAvailableFeatures(
71 &TM.getSubtarget<X86Subtarget>()));
72 }
Daniel Dunbar16cdcb32009-07-28 22:40:46 +000073
Benjamin Kramer38e59892010-07-14 22:38:02 +000074 virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc,
Chris Lattner98986712010-01-14 22:21:20 +000075 SmallVectorImpl<MCParsedAsmOperand*> &Operands);
Kevin Enderby9c656452009-09-10 20:51:44 +000076
77 virtual bool ParseDirective(AsmToken DirectiveID);
Daniel Dunbar16cdcb32009-07-28 22:40:46 +000078};
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +000079
Daniel Dunbarf98bc632010-03-18 20:06:02 +000080class X86_32ATTAsmParser : public X86ATTAsmParser {
81public:
Daniel Dunbard73ada72010-07-19 00:33:49 +000082 X86_32ATTAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &TM)
83 : X86ATTAsmParser(T, _Parser, TM) {
Daniel Dunbarf98bc632010-03-18 20:06:02 +000084 Is64Bit = false;
85 }
86};
87
88class X86_64ATTAsmParser : public X86ATTAsmParser {
89public:
Daniel Dunbard73ada72010-07-19 00:33:49 +000090 X86_64ATTAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &TM)
91 : X86ATTAsmParser(T, _Parser, TM) {
Daniel Dunbarf98bc632010-03-18 20:06:02 +000092 Is64Bit = true;
93 }
94};
95
Chris Lattner37dfdec2009-07-29 06:33:53 +000096} // end anonymous namespace
97
Sean Callanane9b466d2010-01-23 00:40:33 +000098/// @name Auto-generated Match Functions
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +000099/// {
Sean Callanane9b466d2010-01-23 00:40:33 +0000100
Chris Lattnerb8d6e982010-02-09 00:34:28 +0000101static unsigned MatchRegisterName(StringRef Name);
Sean Callanane9b466d2010-01-23 00:40:33 +0000102
103/// }
Chris Lattner37dfdec2009-07-29 06:33:53 +0000104
105namespace {
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000106
107/// X86Operand - Instances of this class represent a parsed X86 machine
108/// instruction.
Chris Lattner45220a82010-01-14 21:20:55 +0000109struct X86Operand : public MCParsedAsmOperand {
Chris Lattner1f19f0f2010-01-15 19:06:59 +0000110 enum KindTy {
Daniel Dunbar20927f22009-08-07 08:26:05 +0000111 Token,
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000112 Register,
113 Immediate,
114 Memory
115 } Kind;
116
Chris Lattner29ef9a22010-01-15 18:51:29 +0000117 SMLoc StartLoc, EndLoc;
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000118
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000119 union {
120 struct {
Daniel Dunbar20927f22009-08-07 08:26:05 +0000121 const char *Data;
122 unsigned Length;
123 } Tok;
124
125 struct {
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000126 unsigned RegNo;
127 } Reg;
128
129 struct {
Daniel Dunbar8c2eebe2009-08-31 08:08:38 +0000130 const MCExpr *Val;
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000131 } Imm;
132
133 struct {
134 unsigned SegReg;
Daniel Dunbar8c2eebe2009-08-31 08:08:38 +0000135 const MCExpr *Disp;
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000136 unsigned BaseReg;
137 unsigned IndexReg;
138 unsigned Scale;
139 } Mem;
Daniel Dunbardbd692a2009-07-20 20:01:54 +0000140 };
Daniel Dunbar092a9dd2009-07-17 20:42:00 +0000141
Chris Lattner0a3c5a52010-01-15 19:33:43 +0000142 X86Operand(KindTy K, SMLoc Start, SMLoc End)
Chris Lattner1f19f0f2010-01-15 19:06:59 +0000143 : Kind(K), StartLoc(Start), EndLoc(End) {}
Daniel Dunbarc918d602010-05-04 16:12:42 +0000144
Chris Lattner1f19f0f2010-01-15 19:06:59 +0000145 /// getStartLoc - Get the location of the first token of this operand.
146 SMLoc getStartLoc() const { return StartLoc; }
147 /// getEndLoc - Get the location of the last token of this operand.
148 SMLoc getEndLoc() const { return EndLoc; }
149
Daniel Dunbarb3cb6962010-08-11 06:37:04 +0000150 virtual void dump(raw_ostream &OS) const {}
151
Daniel Dunbar20927f22009-08-07 08:26:05 +0000152 StringRef getToken() const {
153 assert(Kind == Token && "Invalid access!");
154 return StringRef(Tok.Data, Tok.Length);
155 }
Daniel Dunbarc918d602010-05-04 16:12:42 +0000156 void setTokenValue(StringRef Value) {
157 assert(Kind == Token && "Invalid access!");
158 Tok.Data = Value.data();
159 Tok.Length = Value.size();
160 }
Daniel Dunbar20927f22009-08-07 08:26:05 +0000161
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000162 unsigned getReg() const {
163 assert(Kind == Register && "Invalid access!");
164 return Reg.RegNo;
165 }
Daniel Dunbara2edbab2009-07-28 20:47:52 +0000166
Daniel Dunbar8c2eebe2009-08-31 08:08:38 +0000167 const MCExpr *getImm() const {
Daniel Dunbar022e2a82009-07-31 20:53:16 +0000168 assert(Kind == Immediate && "Invalid access!");
169 return Imm.Val;
170 }
171
Daniel Dunbar8c2eebe2009-08-31 08:08:38 +0000172 const MCExpr *getMemDisp() const {
Daniel Dunbar022e2a82009-07-31 20:53:16 +0000173 assert(Kind == Memory && "Invalid access!");
174 return Mem.Disp;
175 }
176 unsigned getMemSegReg() const {
177 assert(Kind == Memory && "Invalid access!");
178 return Mem.SegReg;
179 }
180 unsigned getMemBaseReg() const {
181 assert(Kind == Memory && "Invalid access!");
182 return Mem.BaseReg;
183 }
184 unsigned getMemIndexReg() const {
185 assert(Kind == Memory && "Invalid access!");
186 return Mem.IndexReg;
187 }
188 unsigned getMemScale() const {
189 assert(Kind == Memory && "Invalid access!");
190 return Mem.Scale;
191 }
192
Daniel Dunbara3741fa2009-08-08 07:50:56 +0000193 bool isToken() const {return Kind == Token; }
Daniel Dunbar20927f22009-08-07 08:26:05 +0000194
195 bool isImm() const { return Kind == Immediate; }
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000196
Daniel Dunbar62e4c672010-05-22 21:02:33 +0000197 bool isImmSExti16i8() const {
Daniel Dunbar5fe63382009-08-09 07:20:21 +0000198 if (!isImm())
199 return false;
200
Daniel Dunbar62e4c672010-05-22 21:02:33 +0000201 // If this isn't a constant expr, just assume it fits and let relaxation
202 // handle it.
203 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
204 if (!CE)
205 return true;
Daniel Dunbar5fe63382009-08-09 07:20:21 +0000206
Daniel Dunbar62e4c672010-05-22 21:02:33 +0000207 // Otherwise, check the value is in a range that makes sense for this
208 // extension.
209 uint64_t Value = CE->getValue();
210 return (( Value <= 0x000000000000007FULL)||
211 (0x000000000000FF80ULL <= Value && Value <= 0x000000000000FFFFULL)||
212 (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
Daniel Dunbar5fe63382009-08-09 07:20:21 +0000213 }
Daniel Dunbar62e4c672010-05-22 21:02:33 +0000214 bool isImmSExti32i8() const {
Daniel Dunbar1fe591d2010-05-20 20:20:39 +0000215 if (!isImm())
216 return false;
217
Daniel Dunbar62e4c672010-05-22 21:02:33 +0000218 // If this isn't a constant expr, just assume it fits and let relaxation
219 // handle it.
220 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
221 if (!CE)
222 return true;
Daniel Dunbar1fe591d2010-05-20 20:20:39 +0000223
Daniel Dunbar62e4c672010-05-22 21:02:33 +0000224 // Otherwise, check the value is in a range that makes sense for this
225 // extension.
226 uint64_t Value = CE->getValue();
227 return (( Value <= 0x000000000000007FULL)||
228 (0x00000000FFFFFF80ULL <= Value && Value <= 0x00000000FFFFFFFFULL)||
229 (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
230 }
231 bool isImmSExti64i8() const {
232 if (!isImm())
233 return false;
234
235 // If this isn't a constant expr, just assume it fits and let relaxation
236 // handle it.
237 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
238 if (!CE)
239 return true;
240
241 // Otherwise, check the value is in a range that makes sense for this
242 // extension.
243 uint64_t Value = CE->getValue();
244 return (( Value <= 0x000000000000007FULL)||
245 (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
246 }
247 bool isImmSExti64i32() const {
248 if (!isImm())
249 return false;
250
251 // If this isn't a constant expr, just assume it fits and let relaxation
252 // handle it.
253 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
254 if (!CE)
255 return true;
256
257 // Otherwise, check the value is in a range that makes sense for this
258 // extension.
259 uint64_t Value = CE->getValue();
260 return (( Value <= 0x000000007FFFFFFFULL)||
261 (0xFFFFFFFF80000000ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
Daniel Dunbar1fe591d2010-05-20 20:20:39 +0000262 }
263
Daniel Dunbar20927f22009-08-07 08:26:05 +0000264 bool isMem() const { return Kind == Memory; }
265
Daniel Dunbarb834f5d2010-01-30 01:02:48 +0000266 bool isAbsMem() const {
267 return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
Daniel Dunbar7b9147a2010-02-02 21:44:16 +0000268 !getMemIndexReg() && getMemScale() == 1;
Daniel Dunbarb834f5d2010-01-30 01:02:48 +0000269 }
270
Daniel Dunbar20927f22009-08-07 08:26:05 +0000271 bool isReg() const { return Kind == Register; }
272
Daniel Dunbar9c60f532010-02-13 00:17:21 +0000273 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
274 // Add as immediates when possible.
275 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
276 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
277 else
278 Inst.addOperand(MCOperand::CreateExpr(Expr));
279 }
280
Daniel Dunbar5c468e32009-08-10 21:00:45 +0000281 void addRegOperands(MCInst &Inst, unsigned N) const {
Daniel Dunbar20927f22009-08-07 08:26:05 +0000282 assert(N == 1 && "Invalid number of operands!");
283 Inst.addOperand(MCOperand::CreateReg(getReg()));
284 }
285
Daniel Dunbar5c468e32009-08-10 21:00:45 +0000286 void addImmOperands(MCInst &Inst, unsigned N) const {
Daniel Dunbar20927f22009-08-07 08:26:05 +0000287 assert(N == 1 && "Invalid number of operands!");
Daniel Dunbar9c60f532010-02-13 00:17:21 +0000288 addExpr(Inst, getImm());
Daniel Dunbar20927f22009-08-07 08:26:05 +0000289 }
290
Daniel Dunbar5c468e32009-08-10 21:00:45 +0000291 void addMemOperands(MCInst &Inst, unsigned N) const {
Daniel Dunbarec2b1f12010-01-30 00:24:00 +0000292 assert((N == 5) && "Invalid number of operands!");
Daniel Dunbar20927f22009-08-07 08:26:05 +0000293 Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
294 Inst.addOperand(MCOperand::CreateImm(getMemScale()));
295 Inst.addOperand(MCOperand::CreateReg(getMemIndexReg()));
Daniel Dunbar9c60f532010-02-13 00:17:21 +0000296 addExpr(Inst, getMemDisp());
Daniel Dunbarec2b1f12010-01-30 00:24:00 +0000297 Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
298 }
Daniel Dunbar20927f22009-08-07 08:26:05 +0000299
Daniel Dunbarb834f5d2010-01-30 01:02:48 +0000300 void addAbsMemOperands(MCInst &Inst, unsigned N) const {
301 assert((N == 1) && "Invalid number of operands!");
302 Inst.addOperand(MCOperand::CreateExpr(getMemDisp()));
303 }
304
Chris Lattnerb4307b32010-01-15 19:28:38 +0000305 static X86Operand *CreateToken(StringRef Str, SMLoc Loc) {
306 X86Operand *Res = new X86Operand(Token, Loc, Loc);
Chris Lattner29ef9a22010-01-15 18:51:29 +0000307 Res->Tok.Data = Str.data();
308 Res->Tok.Length = Str.size();
Daniel Dunbar20927f22009-08-07 08:26:05 +0000309 return Res;
310 }
311
Chris Lattner29ef9a22010-01-15 18:51:29 +0000312 static X86Operand *CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc) {
Chris Lattner1f19f0f2010-01-15 19:06:59 +0000313 X86Operand *Res = new X86Operand(Register, StartLoc, EndLoc);
Chris Lattner29ef9a22010-01-15 18:51:29 +0000314 Res->Reg.RegNo = RegNo;
Chris Lattner29ef9a22010-01-15 18:51:29 +0000315 return Res;
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000316 }
Daniel Dunbar20927f22009-08-07 08:26:05 +0000317
Chris Lattnerb4307b32010-01-15 19:28:38 +0000318 static X86Operand *CreateImm(const MCExpr *Val, SMLoc StartLoc, SMLoc EndLoc){
319 X86Operand *Res = new X86Operand(Immediate, StartLoc, EndLoc);
Chris Lattner29ef9a22010-01-15 18:51:29 +0000320 Res->Imm.Val = Val;
321 return Res;
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000322 }
Daniel Dunbar20927f22009-08-07 08:26:05 +0000323
Daniel Dunbarb834f5d2010-01-30 01:02:48 +0000324 /// Create an absolute memory operand.
325 static X86Operand *CreateMem(const MCExpr *Disp, SMLoc StartLoc,
326 SMLoc EndLoc) {
327 X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc);
328 Res->Mem.SegReg = 0;
329 Res->Mem.Disp = Disp;
330 Res->Mem.BaseReg = 0;
331 Res->Mem.IndexReg = 0;
Daniel Dunbar7b9147a2010-02-02 21:44:16 +0000332 Res->Mem.Scale = 1;
Daniel Dunbarb834f5d2010-01-30 01:02:48 +0000333 return Res;
334 }
335
336 /// Create a generalized memory operand.
Chris Lattner309264d2010-01-15 18:44:13 +0000337 static X86Operand *CreateMem(unsigned SegReg, const MCExpr *Disp,
338 unsigned BaseReg, unsigned IndexReg,
Chris Lattner0a3c5a52010-01-15 19:33:43 +0000339 unsigned Scale, SMLoc StartLoc, SMLoc EndLoc) {
Daniel Dunbarb834f5d2010-01-30 01:02:48 +0000340 // We should never just have a displacement, that should be parsed as an
341 // absolute memory operand.
Daniel Dunbarc09e4112009-07-31 22:22:54 +0000342 assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
343
Daniel Dunbar022e2a82009-07-31 20:53:16 +0000344 // The scale should always be one of {1,2,4,8}.
345 assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000346 "Invalid scale!");
Chris Lattner0a3c5a52010-01-15 19:33:43 +0000347 X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc);
Chris Lattner29ef9a22010-01-15 18:51:29 +0000348 Res->Mem.SegReg = SegReg;
349 Res->Mem.Disp = Disp;
350 Res->Mem.BaseReg = BaseReg;
351 Res->Mem.IndexReg = IndexReg;
352 Res->Mem.Scale = Scale;
353 return Res;
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000354 }
355};
Daniel Dunbara3af3702009-07-20 18:55:04 +0000356
Chris Lattner37dfdec2009-07-29 06:33:53 +0000357} // end anonymous namespace.
Daniel Dunbara2edbab2009-07-28 20:47:52 +0000358
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000359
Chris Lattner29ef9a22010-01-15 18:51:29 +0000360bool X86ATTAsmParser::ParseRegister(unsigned &RegNo,
361 SMLoc &StartLoc, SMLoc &EndLoc) {
Chris Lattner23075742010-01-15 18:27:19 +0000362 RegNo = 0;
Sean Callanan18b83232010-01-19 21:44:56 +0000363 const AsmToken &TokPercent = Parser.getTok();
Kevin Enderby7b4608d2009-09-03 17:15:07 +0000364 assert(TokPercent.is(AsmToken::Percent) && "Invalid token kind!");
Chris Lattner29ef9a22010-01-15 18:51:29 +0000365 StartLoc = TokPercent.getLoc();
Sean Callananb9a25b72010-01-19 20:27:46 +0000366 Parser.Lex(); // Eat percent token.
Kevin Enderby7b4608d2009-09-03 17:15:07 +0000367
Sean Callanan18b83232010-01-19 21:44:56 +0000368 const AsmToken &Tok = Parser.getTok();
Kevin Enderby0d6cd002009-09-16 17:18:29 +0000369 if (Tok.isNot(AsmToken::Identifier))
370 return Error(Tok.getLoc(), "invalid register name");
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000371
Daniel Dunbar0e2771f2009-07-29 00:02:19 +0000372 // FIXME: Validate register for the current architecture; we have to do
373 // validation later, so maybe there is no need for this here.
Kevin Enderby7b4608d2009-09-03 17:15:07 +0000374 RegNo = MatchRegisterName(Tok.getString());
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000375
Bruno Cardoso Lopes3c8e1be2010-07-24 00:06:39 +0000376 // FIXME: This should be done using Requires<In32BitMode> and
377 // Requires<In64BitMode> so "eiz" usage in 64-bit instructions
378 // can be also checked.
379 if (RegNo == X86::RIZ && !Is64Bit)
380 return Error(Tok.getLoc(), "riz register in 64-bit mode only");
381
Chris Lattnere16b0fc2010-02-09 00:49:22 +0000382 // Parse %st(1) and "%st" as "%st(0)"
383 if (RegNo == 0 && Tok.getString() == "st") {
384 RegNo = X86::ST0;
385 EndLoc = Tok.getLoc();
386 Parser.Lex(); // Eat 'st'
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000387
Chris Lattnere16b0fc2010-02-09 00:49:22 +0000388 // Check to see if we have '(4)' after %st.
389 if (getLexer().isNot(AsmToken::LParen))
390 return false;
391 // Lex the paren.
392 getParser().Lex();
393
394 const AsmToken &IntTok = Parser.getTok();
395 if (IntTok.isNot(AsmToken::Integer))
396 return Error(IntTok.getLoc(), "expected stack index");
397 switch (IntTok.getIntVal()) {
398 case 0: RegNo = X86::ST0; break;
399 case 1: RegNo = X86::ST1; break;
400 case 2: RegNo = X86::ST2; break;
401 case 3: RegNo = X86::ST3; break;
402 case 4: RegNo = X86::ST4; break;
403 case 5: RegNo = X86::ST5; break;
404 case 6: RegNo = X86::ST6; break;
405 case 7: RegNo = X86::ST7; break;
406 default: return Error(IntTok.getLoc(), "invalid stack index");
407 }
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000408
Chris Lattnere16b0fc2010-02-09 00:49:22 +0000409 if (getParser().Lex().isNot(AsmToken::RParen))
410 return Error(Parser.getTok().getLoc(), "expected ')'");
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000411
Chris Lattnere16b0fc2010-02-09 00:49:22 +0000412 EndLoc = Tok.getLoc();
413 Parser.Lex(); // Eat ')'
414 return false;
415 }
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000416
Chris Lattner645b2092010-06-24 07:29:18 +0000417 // If this is "db[0-7]", match it as an alias
418 // for dr[0-7].
419 if (RegNo == 0 && Tok.getString().size() == 3 &&
420 Tok.getString().startswith("db")) {
421 switch (Tok.getString()[2]) {
422 case '0': RegNo = X86::DR0; break;
423 case '1': RegNo = X86::DR1; break;
424 case '2': RegNo = X86::DR2; break;
425 case '3': RegNo = X86::DR3; break;
426 case '4': RegNo = X86::DR4; break;
427 case '5': RegNo = X86::DR5; break;
428 case '6': RegNo = X86::DR6; break;
429 case '7': RegNo = X86::DR7; break;
430 }
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000431
Chris Lattner645b2092010-06-24 07:29:18 +0000432 if (RegNo != 0) {
433 EndLoc = Tok.getLoc();
434 Parser.Lex(); // Eat it.
435 return false;
436 }
437 }
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000438
Daniel Dunbar245f0582009-08-08 21:22:41 +0000439 if (RegNo == 0)
Daniel Dunbar0e2771f2009-07-29 00:02:19 +0000440 return Error(Tok.getLoc(), "invalid register name");
441
Chris Lattner29ef9a22010-01-15 18:51:29 +0000442 EndLoc = Tok.getLoc();
Sean Callananb9a25b72010-01-19 20:27:46 +0000443 Parser.Lex(); // Eat identifier token.
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000444 return false;
Daniel Dunbar092a9dd2009-07-17 20:42:00 +0000445}
446
Chris Lattner309264d2010-01-15 18:44:13 +0000447X86Operand *X86ATTAsmParser::ParseOperand() {
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000448 switch (getLexer().getKind()) {
449 default:
Chris Lattnereef6d782010-04-17 18:56:34 +0000450 // Parse a memory operand with no segment register.
451 return ParseMemOperand(0, Parser.getTok().getLoc());
Chris Lattner23075742010-01-15 18:27:19 +0000452 case AsmToken::Percent: {
Chris Lattnereef6d782010-04-17 18:56:34 +0000453 // Read the register.
Chris Lattner23075742010-01-15 18:27:19 +0000454 unsigned RegNo;
Chris Lattner29ef9a22010-01-15 18:51:29 +0000455 SMLoc Start, End;
456 if (ParseRegister(RegNo, Start, End)) return 0;
Bruno Cardoso Lopes3c8e1be2010-07-24 00:06:39 +0000457 if (RegNo == X86::EIZ || RegNo == X86::RIZ) {
458 Error(Start, "eiz and riz can only be used as index registers");
459 return 0;
460 }
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000461
Chris Lattnereef6d782010-04-17 18:56:34 +0000462 // If this is a segment register followed by a ':', then this is the start
463 // of a memory reference, otherwise this is a normal register reference.
464 if (getLexer().isNot(AsmToken::Colon))
465 return X86Operand::CreateReg(RegNo, Start, End);
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000466
467
Chris Lattnereef6d782010-04-17 18:56:34 +0000468 getParser().Lex(); // Eat the colon.
469 return ParseMemOperand(RegNo, Start);
Chris Lattner23075742010-01-15 18:27:19 +0000470 }
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000471 case AsmToken::Dollar: {
472 // $42 -> immediate.
Sean Callanan18b83232010-01-19 21:44:56 +0000473 SMLoc Start = Parser.getTok().getLoc(), End;
Sean Callananb9a25b72010-01-19 20:27:46 +0000474 Parser.Lex();
Daniel Dunbar8c2eebe2009-08-31 08:08:38 +0000475 const MCExpr *Val;
Chris Lattner54482b42010-01-15 19:39:23 +0000476 if (getParser().ParseExpression(Val, End))
Chris Lattner309264d2010-01-15 18:44:13 +0000477 return 0;
Chris Lattnerb4307b32010-01-15 19:28:38 +0000478 return X86Operand::CreateImm(Val, Start, End);
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000479 }
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000480 }
Daniel Dunbardbd692a2009-07-20 20:01:54 +0000481}
482
Chris Lattnereef6d782010-04-17 18:56:34 +0000483/// ParseMemOperand: segment: disp(basereg, indexreg, scale). The '%ds:' prefix
484/// has already been parsed if present.
485X86Operand *X86ATTAsmParser::ParseMemOperand(unsigned SegReg, SMLoc MemStart) {
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000486
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000487 // We have to disambiguate a parenthesized expression "(4+5)" from the start
488 // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)". The
Chris Lattner75f265f2010-01-24 01:07:33 +0000489 // only way to do this without lookahead is to eat the '(' and see what is
490 // after it.
Daniel Dunbar8c2eebe2009-08-31 08:08:38 +0000491 const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext());
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000492 if (getLexer().isNot(AsmToken::LParen)) {
Chris Lattner54482b42010-01-15 19:39:23 +0000493 SMLoc ExprEnd;
494 if (getParser().ParseExpression(Disp, ExprEnd)) return 0;
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000495
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000496 // After parsing the base expression we could either have a parenthesized
497 // memory address or not. If not, return now. If so, eat the (.
498 if (getLexer().isNot(AsmToken::LParen)) {
Daniel Dunbarc09e4112009-07-31 22:22:54 +0000499 // Unless we have a segment register, treat this as an immediate.
Chris Lattner309264d2010-01-15 18:44:13 +0000500 if (SegReg == 0)
Daniel Dunbarb834f5d2010-01-30 01:02:48 +0000501 return X86Operand::CreateMem(Disp, MemStart, ExprEnd);
Chris Lattner0a3c5a52010-01-15 19:33:43 +0000502 return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd);
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000503 }
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000504
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000505 // Eat the '('.
Sean Callananb9a25b72010-01-19 20:27:46 +0000506 Parser.Lex();
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000507 } else {
508 // Okay, we have a '('. We don't know if this is an expression or not, but
509 // so we have to eat the ( to see beyond it.
Sean Callanan18b83232010-01-19 21:44:56 +0000510 SMLoc LParenLoc = Parser.getTok().getLoc();
Sean Callananb9a25b72010-01-19 20:27:46 +0000511 Parser.Lex(); // Eat the '('.
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000512
Kevin Enderby7b4608d2009-09-03 17:15:07 +0000513 if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) {
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000514 // Nothing to do here, fall into the code below with the '(' part of the
515 // memory operand consumed.
516 } else {
Chris Lattnerb4307b32010-01-15 19:28:38 +0000517 SMLoc ExprEnd;
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000518
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000519 // It must be an parenthesized expression, parse it now.
Chris Lattnerb4307b32010-01-15 19:28:38 +0000520 if (getParser().ParseParenExpression(Disp, ExprEnd))
Chris Lattner309264d2010-01-15 18:44:13 +0000521 return 0;
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000522
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000523 // After parsing the base expression we could either have a parenthesized
524 // memory address or not. If not, return now. If so, eat the (.
525 if (getLexer().isNot(AsmToken::LParen)) {
Daniel Dunbarc09e4112009-07-31 22:22:54 +0000526 // Unless we have a segment register, treat this as an immediate.
Chris Lattner309264d2010-01-15 18:44:13 +0000527 if (SegReg == 0)
Daniel Dunbarb834f5d2010-01-30 01:02:48 +0000528 return X86Operand::CreateMem(Disp, LParenLoc, ExprEnd);
Chris Lattner0a3c5a52010-01-15 19:33:43 +0000529 return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd);
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000530 }
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000531
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000532 // Eat the '('.
Sean Callananb9a25b72010-01-19 20:27:46 +0000533 Parser.Lex();
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000534 }
535 }
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000536
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000537 // If we reached here, then we just ate the ( of the memory operand. Process
538 // the rest of the memory operand.
Daniel Dunbar022e2a82009-07-31 20:53:16 +0000539 unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000540
Chris Lattner29ef9a22010-01-15 18:51:29 +0000541 if (getLexer().is(AsmToken::Percent)) {
542 SMLoc L;
543 if (ParseRegister(BaseReg, L, L)) return 0;
Bruno Cardoso Lopes3c8e1be2010-07-24 00:06:39 +0000544 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ) {
545 Error(L, "eiz and riz can only be used as index registers");
546 return 0;
547 }
Chris Lattner29ef9a22010-01-15 18:51:29 +0000548 }
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000549
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000550 if (getLexer().is(AsmToken::Comma)) {
Sean Callananb9a25b72010-01-19 20:27:46 +0000551 Parser.Lex(); // Eat the comma.
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000552
553 // Following the comma we should have either an index register, or a scale
554 // value. We don't support the later form, but we want to parse it
555 // correctly.
556 //
557 // Not that even though it would be completely consistent to support syntax
Bruno Cardoso Lopes3c8e1be2010-07-24 00:06:39 +0000558 // like "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this.
Kevin Enderby7b4608d2009-09-03 17:15:07 +0000559 if (getLexer().is(AsmToken::Percent)) {
Chris Lattner29ef9a22010-01-15 18:51:29 +0000560 SMLoc L;
561 if (ParseRegister(IndexReg, L, L)) return 0;
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000562
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000563 if (getLexer().isNot(AsmToken::RParen)) {
564 // Parse the scale amount:
565 // ::= ',' [scale-expression]
Chris Lattner309264d2010-01-15 18:44:13 +0000566 if (getLexer().isNot(AsmToken::Comma)) {
Sean Callanan18b83232010-01-19 21:44:56 +0000567 Error(Parser.getTok().getLoc(),
Chris Lattner309264d2010-01-15 18:44:13 +0000568 "expected comma in scale expression");
569 return 0;
570 }
Sean Callananb9a25b72010-01-19 20:27:46 +0000571 Parser.Lex(); // Eat the comma.
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000572
573 if (getLexer().isNot(AsmToken::RParen)) {
Sean Callanan18b83232010-01-19 21:44:56 +0000574 SMLoc Loc = Parser.getTok().getLoc();
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000575
576 int64_t ScaleVal;
577 if (getParser().ParseAbsoluteExpression(ScaleVal))
Chris Lattner309264d2010-01-15 18:44:13 +0000578 return 0;
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000579
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000580 // Validate the scale amount.
Chris Lattner309264d2010-01-15 18:44:13 +0000581 if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8){
582 Error(Loc, "scale factor in address must be 1, 2, 4 or 8");
583 return 0;
584 }
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000585 Scale = (unsigned)ScaleVal;
586 }
587 }
588 } else if (getLexer().isNot(AsmToken::RParen)) {
Daniel Dunbaree910252010-08-24 19:13:38 +0000589 // A scale amount without an index is ignored.
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000590 // index.
Sean Callanan18b83232010-01-19 21:44:56 +0000591 SMLoc Loc = Parser.getTok().getLoc();
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000592
593 int64_t Value;
594 if (getParser().ParseAbsoluteExpression(Value))
Chris Lattner309264d2010-01-15 18:44:13 +0000595 return 0;
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000596
Daniel Dunbaree910252010-08-24 19:13:38 +0000597 if (Value != 1)
598 Warning(Loc, "scale factor without index register is ignored");
599 Scale = 1;
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000600 }
601 }
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000602
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000603 // Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
Chris Lattner309264d2010-01-15 18:44:13 +0000604 if (getLexer().isNot(AsmToken::RParen)) {
Sean Callanan18b83232010-01-19 21:44:56 +0000605 Error(Parser.getTok().getLoc(), "unexpected token in memory operand");
Chris Lattner309264d2010-01-15 18:44:13 +0000606 return 0;
607 }
Sean Callanan18b83232010-01-19 21:44:56 +0000608 SMLoc MemEnd = Parser.getTok().getLoc();
Sean Callananb9a25b72010-01-19 20:27:46 +0000609 Parser.Lex(); // Eat the ')'.
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000610
Chris Lattner0a3c5a52010-01-15 19:33:43 +0000611 return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale,
612 MemStart, MemEnd);
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000613}
614
Chris Lattner98986712010-01-14 22:21:20 +0000615bool X86ATTAsmParser::
Benjamin Kramer38e59892010-07-14 22:38:02 +0000616ParseInstruction(StringRef Name, SMLoc NameLoc,
Chris Lattner98986712010-01-14 22:21:20 +0000617 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Daniel Dunbar1b6c0602010-02-10 21:19:28 +0000618 // FIXME: Hack to recognize "sal..." and "rep..." for now. We need a way to
619 // represent alternative syntaxes in the .td file, without requiring
620 // instruction duplication.
621 StringRef PatchedName = StringSwitch<StringRef>(Name)
622 .Case("sal", "shl")
623 .Case("salb", "shlb")
624 .Case("sall", "shll")
625 .Case("salq", "shlq")
626 .Case("salw", "shlw")
627 .Case("repe", "rep")
628 .Case("repz", "rep")
629 .Case("repnz", "repne")
Chris Lattnerba8cea42010-09-08 05:38:31 +0000630 .Case("iret", "iretl")
Chris Lattnerba8e81c2010-09-08 05:45:34 +0000631 .Case("sysret", "sysretl")
Chris Lattnerd68c4742010-09-06 23:40:56 +0000632 .Case("push", Is64Bit ? "pushq" : "pushl")
Chris Lattner373c4582010-09-08 22:13:08 +0000633 .Case("pop", Is64Bit ? "popq" : "popl")
Dan Gohmane5e4ff92010-05-20 16:16:00 +0000634 .Case("pushf", Is64Bit ? "pushfq" : "pushfl")
635 .Case("popf", Is64Bit ? "popfq" : "popfl")
Kevin Enderby9d31d792010-05-21 23:01:38 +0000636 .Case("retl", Is64Bit ? "retl" : "ret")
637 .Case("retq", Is64Bit ? "ret" : "retq")
Daniel Dunbar4c361972010-05-22 06:37:33 +0000638 .Case("setz", "sete")
639 .Case("setnz", "setne")
640 .Case("jz", "je")
641 .Case("jnz", "jne")
Kevin Enderbybd658912010-05-27 21:33:19 +0000642 .Case("jc", "jb")
Kevin Enderbybd658912010-05-27 21:33:19 +0000643 .Case("jna", "jbe")
644 .Case("jnae", "jb")
645 .Case("jnb", "jae")
646 .Case("jnbe", "ja")
647 .Case("jnc", "jae")
648 .Case("jng", "jle")
649 .Case("jnge", "jl")
650 .Case("jnl", "jge")
651 .Case("jnle", "jg")
652 .Case("jpe", "jp")
653 .Case("jpo", "jnp")
Chris Lattnere9e0fc52010-09-07 00:05:45 +0000654 // Condition code aliases for 16-bit, 32-bit, 64-bit and unspec operands.
655 .Case("cmovcw", "cmovbw") .Case("cmovcl", "cmovbl")
656 .Case("cmovcq", "cmovbq") .Case("cmovc", "cmovb")
657 .Case("cmovnaw", "cmovbew").Case("cmovnal", "cmovbel")
658 .Case("cmovnaq", "cmovbeq").Case("cmovna", "cmovbe")
659 .Case("cmovnbw", "cmovaew").Case("cmovnbl", "cmovael")
660 .Case("cmovnbq", "cmovaeq").Case("cmovnb", "cmovae")
661 .Case("cmovnbew","cmovaw") .Case("cmovnbel","cmoval")
662 .Case("cmovnbeq","cmovaq") .Case("cmovnbe", "cmova")
663 .Case("cmovncw", "cmovaew").Case("cmovncl", "cmovael")
664 .Case("cmovncq", "cmovaeq").Case("cmovnc", "cmovae")
665 .Case("cmovngw", "cmovlew").Case("cmovngl", "cmovlel")
666 .Case("cmovngq", "cmovleq").Case("cmovng", "cmovle")
667 .Case("cmovnw", "cmovgew").Case("cmovnl", "cmovgel")
668 .Case("cmovnq", "cmovgeq").Case("cmovn", "cmovge")
669 .Case("cmovngw", "cmovlew").Case("cmovngl", "cmovlel")
670 .Case("cmovngq", "cmovleq").Case("cmovng", "cmovle")
671 .Case("cmovngew","cmovlw") .Case("cmovngel","cmovll")
672 .Case("cmovngeq","cmovlq") .Case("cmovnge", "cmovl")
673 .Case("cmovnlw", "cmovgew").Case("cmovnll", "cmovgel")
674 .Case("cmovnlq", "cmovgeq").Case("cmovnl", "cmovge")
675 .Case("cmovnlew","cmovgw") .Case("cmovnlel","cmovgl")
676 .Case("cmovnleq","cmovgq") .Case("cmovnle", "cmovg")
677 .Case("cmovnzw", "cmovnew").Case("cmovnzl", "cmovnel")
678 .Case("cmovnzq", "cmovneq").Case("cmovnz", "cmovne")
679 .Case("cmovzw", "cmovew") .Case("cmovzl", "cmovel")
680 .Case("cmovzq", "cmoveq") .Case("cmovz", "cmove")
Kevin Enderby5e394422010-05-28 20:59:10 +0000681 .Case("fwait", "wait")
Kevin Enderby31cc9652010-05-28 21:20:21 +0000682 .Case("movzx", "movzb")
Daniel Dunbar1b6c0602010-02-10 21:19:28 +0000683 .Default(Name);
Daniel Dunbar39e2dd72010-05-25 19:49:32 +0000684
685 // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}.
686 const MCExpr *ExtraImmOp = 0;
Bruno Cardoso Lopes428256b2010-06-23 21:10:57 +0000687 if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) &&
Daniel Dunbar39e2dd72010-05-25 19:49:32 +0000688 (PatchedName.endswith("ss") || PatchedName.endswith("sd") ||
689 PatchedName.endswith("ps") || PatchedName.endswith("pd"))) {
Bruno Cardoso Lopes428256b2010-06-23 21:10:57 +0000690 bool IsVCMP = PatchedName.startswith("vcmp");
691 unsigned SSECCIdx = IsVCMP ? 4 : 3;
Daniel Dunbar39e2dd72010-05-25 19:49:32 +0000692 unsigned SSEComparisonCode = StringSwitch<unsigned>(
Bruno Cardoso Lopes428256b2010-06-23 21:10:57 +0000693 PatchedName.slice(SSECCIdx, PatchedName.size() - 2))
Bruno Cardoso Lopescc69e132010-07-07 22:24:03 +0000694 .Case("eq", 0)
695 .Case("lt", 1)
696 .Case("le", 2)
697 .Case("unord", 3)
698 .Case("neq", 4)
699 .Case("nlt", 5)
700 .Case("nle", 6)
701 .Case("ord", 7)
702 .Case("eq_uq", 8)
703 .Case("nge", 9)
704 .Case("ngt", 0x0A)
705 .Case("false", 0x0B)
706 .Case("neq_oq", 0x0C)
707 .Case("ge", 0x0D)
708 .Case("gt", 0x0E)
709 .Case("true", 0x0F)
710 .Case("eq_os", 0x10)
711 .Case("lt_oq", 0x11)
712 .Case("le_oq", 0x12)
713 .Case("unord_s", 0x13)
714 .Case("neq_us", 0x14)
715 .Case("nlt_uq", 0x15)
716 .Case("nle_uq", 0x16)
717 .Case("ord_s", 0x17)
718 .Case("eq_us", 0x18)
719 .Case("nge_uq", 0x19)
720 .Case("ngt_uq", 0x1A)
721 .Case("false_os", 0x1B)
722 .Case("neq_os", 0x1C)
723 .Case("ge_oq", 0x1D)
724 .Case("gt_oq", 0x1E)
725 .Case("true_us", 0x1F)
Daniel Dunbar39e2dd72010-05-25 19:49:32 +0000726 .Default(~0U);
727 if (SSEComparisonCode != ~0U) {
728 ExtraImmOp = MCConstantExpr::Create(SSEComparisonCode,
729 getParser().getContext());
730 if (PatchedName.endswith("ss")) {
Bruno Cardoso Lopes428256b2010-06-23 21:10:57 +0000731 PatchedName = IsVCMP ? "vcmpss" : "cmpss";
Daniel Dunbar39e2dd72010-05-25 19:49:32 +0000732 } else if (PatchedName.endswith("sd")) {
Bruno Cardoso Lopes428256b2010-06-23 21:10:57 +0000733 PatchedName = IsVCMP ? "vcmpsd" : "cmpsd";
Daniel Dunbar39e2dd72010-05-25 19:49:32 +0000734 } else if (PatchedName.endswith("ps")) {
Bruno Cardoso Lopes428256b2010-06-23 21:10:57 +0000735 PatchedName = IsVCMP ? "vcmpps" : "cmpps";
Daniel Dunbar39e2dd72010-05-25 19:49:32 +0000736 } else {
737 assert(PatchedName.endswith("pd") && "Unexpected mnemonic!");
Bruno Cardoso Lopes428256b2010-06-23 21:10:57 +0000738 PatchedName = IsVCMP ? "vcmppd" : "cmppd";
Daniel Dunbar39e2dd72010-05-25 19:49:32 +0000739 }
740 }
741 }
Bruno Cardoso Lopesf528d2b2010-07-23 18:41:12 +0000742
743 // FIXME: Hack to recognize vpclmul<src1_quadword, src2_quadword>dq
744 if (PatchedName.startswith("vpclmul")) {
745 unsigned CLMULQuadWordSelect = StringSwitch<unsigned>(
746 PatchedName.slice(7, PatchedName.size() - 2))
747 .Case("lqlq", 0x00) // src1[63:0], src2[63:0]
748 .Case("hqlq", 0x01) // src1[127:64], src2[63:0]
749 .Case("lqhq", 0x10) // src1[63:0], src2[127:64]
750 .Case("hqhq", 0x11) // src1[127:64], src2[127:64]
751 .Default(~0U);
752 if (CLMULQuadWordSelect != ~0U) {
753 ExtraImmOp = MCConstantExpr::Create(CLMULQuadWordSelect,
754 getParser().getContext());
755 assert(PatchedName.endswith("dq") && "Unexpected mnemonic!");
756 PatchedName = "vpclmulqdq";
757 }
758 }
Chris Lattner9607c402010-09-08 04:53:27 +0000759
Daniel Dunbar1b6c0602010-02-10 21:19:28 +0000760 Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000761
Daniel Dunbar39e2dd72010-05-25 19:49:32 +0000762 if (ExtraImmOp)
763 Operands.push_back(X86Operand::CreateImm(ExtraImmOp, NameLoc, NameLoc));
Chris Lattner47ab90b2010-09-06 18:32:06 +0000764
Chris Lattner2544f422010-09-08 05:17:37 +0000765
766 // Determine whether this is an instruction prefix.
767 bool isPrefix =
768 PatchedName == "lock" || PatchedName == "rep" ||
769 PatchedName == "repne";
770
771
772 // This does the actual operand parsing. Don't parse any more if we have a
773 // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we
774 // just want to parse the "lock" as the first instruction and the "incl" as
775 // the next one.
776 if (getLexer().isNot(AsmToken::EndOfStatement) && !isPrefix) {
Daniel Dunbar0db68f42009-08-11 05:00:25 +0000777
778 // Parse '*' modifier.
779 if (getLexer().is(AsmToken::Star)) {
Sean Callanan18b83232010-01-19 21:44:56 +0000780 SMLoc Loc = Parser.getTok().getLoc();
Chris Lattnerb4307b32010-01-15 19:28:38 +0000781 Operands.push_back(X86Operand::CreateToken("*", Loc));
Sean Callananb9a25b72010-01-19 20:27:46 +0000782 Parser.Lex(); // Eat the star.
Daniel Dunbar0db68f42009-08-11 05:00:25 +0000783 }
784
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000785 // Read the first operand.
Chris Lattner309264d2010-01-15 18:44:13 +0000786 if (X86Operand *Op = ParseOperand())
787 Operands.push_back(Op);
Chris Lattnercbf8a982010-09-11 16:18:25 +0000788 else {
789 Parser.EatToEndOfStatement();
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000790 return true;
Chris Lattnercbf8a982010-09-11 16:18:25 +0000791 }
Daniel Dunbar39e2dd72010-05-25 19:49:32 +0000792
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000793 while (getLexer().is(AsmToken::Comma)) {
Sean Callananb9a25b72010-01-19 20:27:46 +0000794 Parser.Lex(); // Eat the comma.
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000795
796 // Parse and remember the operand.
Chris Lattner309264d2010-01-15 18:44:13 +0000797 if (X86Operand *Op = ParseOperand())
798 Operands.push_back(Op);
Chris Lattnercbf8a982010-09-11 16:18:25 +0000799 else {
800 Parser.EatToEndOfStatement();
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000801 return true;
Chris Lattnercbf8a982010-09-11 16:18:25 +0000802 }
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000803 }
Chris Lattner2544f422010-09-08 05:17:37 +0000804
Chris Lattnercbf8a982010-09-11 16:18:25 +0000805 if (getLexer().isNot(AsmToken::EndOfStatement)) {
806 Parser.EatToEndOfStatement();
Chris Lattner2544f422010-09-08 05:17:37 +0000807 return TokError("unexpected token in argument list");
Chris Lattnercbf8a982010-09-11 16:18:25 +0000808 }
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000809 }
Chris Lattner34e53142010-09-08 05:10:46 +0000810
Chris Lattner2544f422010-09-08 05:17:37 +0000811 if (getLexer().is(AsmToken::EndOfStatement))
812 Parser.Lex(); // Consume the EndOfStatement
Daniel Dunbar16cdcb32009-07-28 22:40:46 +0000813
Daniel Dunbard5e77052010-03-13 00:47:29 +0000814 // FIXME: Hack to handle recognizing s{hr,ar,hl}? $1.
815 if ((Name.startswith("shr") || Name.startswith("sar") ||
816 Name.startswith("shl")) &&
Chris Lattner47ab90b2010-09-06 18:32:06 +0000817 Operands.size() == 3) {
818 X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]);
819 if (Op1->isImm() && isa<MCConstantExpr>(Op1->getImm()) &&
820 cast<MCConstantExpr>(Op1->getImm())->getValue() == 1) {
821 delete Operands[1];
822 Operands.erase(Operands.begin() + 1);
823 }
Daniel Dunbarf2de13f2010-03-20 22:36:38 +0000824 }
Daniel Dunbard5e77052010-03-13 00:47:29 +0000825
Kevin Enderbycf50a532010-05-25 20:52:34 +0000826 // FIXME: Hack to handle "f{mul*,add*,sub*,div*} $op, st(0)" the same as
827 // "f{mul*,add*,sub*,div*} $op"
828 if ((Name.startswith("fmul") || Name.startswith("fadd") ||
829 Name.startswith("fsub") || Name.startswith("fdiv")) &&
830 Operands.size() == 3 &&
831 static_cast<X86Operand*>(Operands[2])->isReg() &&
832 static_cast<X86Operand*>(Operands[2])->getReg() == X86::ST0) {
833 delete Operands[2];
834 Operands.erase(Operands.begin() + 2);
835 }
836
Daniel Dunbarfba88d42010-08-24 19:37:56 +0000837 // FIXME: Hack to handle "imul <imm>, B" which is an alias for "imul <imm>, B,
838 // B".
Daniel Dunbarae528f62010-08-24 19:24:18 +0000839 if (Name.startswith("imul") && Operands.size() == 3 &&
Daniel Dunbarfba88d42010-08-24 19:37:56 +0000840 static_cast<X86Operand*>(Operands[1])->isImm() &&
Daniel Dunbarae528f62010-08-24 19:24:18 +0000841 static_cast<X86Operand*>(Operands.back())->isReg()) {
842 X86Operand *Op = static_cast<X86Operand*>(Operands.back());
843 Operands.push_back(X86Operand::CreateReg(Op->getReg(), Op->getStartLoc(),
844 Op->getEndLoc()));
845 }
Chris Lattnerc5cebeb2010-09-06 23:51:44 +0000846
847 // 'sldt <mem>' can be encoded with either sldtw or sldtq with the same
848 // effect (both store to a 16-bit mem). Force to sldtw to avoid ambiguity
849 // errors, since its encoding is the most compact.
850 if (Name == "sldt" && Operands.size() == 2 &&
Benjamin Krameraceeb3a2010-09-07 14:40:58 +0000851 static_cast<X86Operand*>(Operands[1])->isMem()) {
852 delete Operands[0];
Chris Lattnerc5cebeb2010-09-06 23:51:44 +0000853 Operands[0] = X86Operand::CreateToken("sldtw", NameLoc);
Benjamin Krameraceeb3a2010-09-07 14:40:58 +0000854 }
Chris Lattner9607c402010-09-08 04:53:27 +0000855
856 // The assembler accepts "xchgX <reg>, <mem>" and "xchgX <mem>, <reg>" as
857 // synonyms. Our tables only have the "<reg>, <mem>" form, so if we see the
858 // other operand order, swap them.
Chris Lattner90b54542010-09-08 22:27:05 +0000859 if (Name == "xchgb" || Name == "xchgw" || Name == "xchgl" || Name == "xchgq"||
860 Name == "xchg")
Chris Lattner9607c402010-09-08 04:53:27 +0000861 if (Operands.size() == 3 &&
862 static_cast<X86Operand*>(Operands[1])->isMem() &&
863 static_cast<X86Operand*>(Operands[2])->isReg()) {
864 std::swap(Operands[1], Operands[2]);
865 }
Daniel Dunbarae528f62010-08-24 19:24:18 +0000866
Chris Lattnerc8ae35a2010-09-08 05:51:12 +0000867 // The assembler accepts "testX <reg>, <mem>" and "testX <mem>, <reg>" as
868 // synonyms. Our tables only have the "<mem>, <reg>" form, so if we see the
869 // other operand order, swap them.
Chris Lattner90b54542010-09-08 22:27:05 +0000870 if (Name == "testb" || Name == "testw" || Name == "testl" || Name == "testq"||
871 Name == "test")
Chris Lattnerc8ae35a2010-09-08 05:51:12 +0000872 if (Operands.size() == 3 &&
873 static_cast<X86Operand*>(Operands[1])->isReg() &&
874 static_cast<X86Operand*>(Operands[2])->isMem()) {
875 std::swap(Operands[1], Operands[2]);
876 }
877
Chris Lattner98986712010-01-14 22:21:20 +0000878 return false;
Daniel Dunbara3af3702009-07-20 18:55:04 +0000879}
880
Kevin Enderby9c656452009-09-10 20:51:44 +0000881bool X86ATTAsmParser::ParseDirective(AsmToken DirectiveID) {
882 StringRef IDVal = DirectiveID.getIdentifier();
883 if (IDVal == ".word")
884 return ParseDirectiveWord(2, DirectiveID.getLoc());
885 return true;
886}
887
888/// ParseDirectiveWord
889/// ::= .word [ expression (, expression)* ]
890bool X86ATTAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
891 if (getLexer().isNot(AsmToken::EndOfStatement)) {
892 for (;;) {
893 const MCExpr *Value;
894 if (getParser().ParseExpression(Value))
895 return true;
896
Chris Lattneraaec2052010-01-19 19:46:13 +0000897 getParser().getStreamer().EmitValue(Value, Size, 0 /*addrspace*/);
Kevin Enderby9c656452009-09-10 20:51:44 +0000898
899 if (getLexer().is(AsmToken::EndOfStatement))
900 break;
Bruno Cardoso Lopesf64a7d42010-07-23 22:15:26 +0000901
Kevin Enderby9c656452009-09-10 20:51:44 +0000902 // FIXME: Improve diagnostic.
903 if (getLexer().isNot(AsmToken::Comma))
904 return Error(L, "unexpected token in directive");
Sean Callananb9a25b72010-01-19 20:27:46 +0000905 Parser.Lex();
Kevin Enderby9c656452009-09-10 20:51:44 +0000906 }
907 }
908
Sean Callananb9a25b72010-01-19 20:27:46 +0000909 Parser.Lex();
Kevin Enderby9c656452009-09-10 20:51:44 +0000910 return false;
911}
912
Daniel Dunbarf1e29d42010-08-12 00:55:38 +0000913
Daniel Dunbarc918d602010-05-04 16:12:42 +0000914bool
Daniel Dunbarf1e29d42010-08-12 00:55:38 +0000915X86ATTAsmParser::MatchInstruction(SMLoc IDLoc,
916 const SmallVectorImpl<MCParsedAsmOperand*>
Daniel Dunbarc918d602010-05-04 16:12:42 +0000917 &Operands,
918 MCInst &Inst) {
Daniel Dunbarf1e29d42010-08-12 00:55:38 +0000919 assert(!Operands.empty() && "Unexpect empty operand list!");
920
Chris Lattnera008e8a2010-09-06 21:54:15 +0000921 bool WasOriginallyInvalidOperand = false;
Chris Lattnerce4a3352010-09-06 22:11:18 +0000922 unsigned OrigErrorInfo;
Chris Lattnera008e8a2010-09-06 21:54:15 +0000923
Daniel Dunbarc918d602010-05-04 16:12:42 +0000924 // First, try a direct match.
Chris Lattnerce4a3352010-09-06 22:11:18 +0000925 switch (MatchInstructionImpl(Operands, Inst, OrigErrorInfo)) {
Chris Lattnerec6789f2010-09-06 20:08:02 +0000926 case Match_Success:
Daniel Dunbarc918d602010-05-04 16:12:42 +0000927 return false;
Chris Lattnerec6789f2010-09-06 20:08:02 +0000928 case Match_MissingFeature:
929 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
930 return true;
Chris Lattnera008e8a2010-09-06 21:54:15 +0000931 case Match_InvalidOperand:
932 WasOriginallyInvalidOperand = true;
933 break;
934 case Match_MnemonicFail:
Chris Lattnerec6789f2010-09-06 20:08:02 +0000935 break;
936 }
Daniel Dunbarc918d602010-05-04 16:12:42 +0000937
Daniel Dunbarc918d602010-05-04 16:12:42 +0000938 // FIXME: Ideally, we would only attempt suffix matches for things which are
939 // valid prefixes, and we could just infer the right unambiguous
940 // type. However, that requires substantially more matcher support than the
941 // following hack.
942
Chris Lattner0692ee62010-09-06 19:11:01 +0000943 X86Operand *Op = static_cast<X86Operand*>(Operands[0]);
944 assert(Op->isToken() && "Leading operand should always be a mnemonic!");
945
Daniel Dunbarc918d602010-05-04 16:12:42 +0000946 // Change the operand to point to a temporary token.
Daniel Dunbarc918d602010-05-04 16:12:42 +0000947 StringRef Base = Op->getToken();
Daniel Dunbarf1e29d42010-08-12 00:55:38 +0000948 SmallString<16> Tmp;
949 Tmp += Base;
950 Tmp += ' ';
951 Op->setTokenValue(Tmp.str());
Daniel Dunbarc918d602010-05-04 16:12:42 +0000952
953 // Check for the various suffix matches.
954 Tmp[Base.size()] = 'b';
Chris Lattnerce4a3352010-09-06 22:11:18 +0000955 unsigned BErrorInfo, WErrorInfo, LErrorInfo, QErrorInfo;
956 MatchResultTy MatchB = MatchInstructionImpl(Operands, Inst, BErrorInfo);
Daniel Dunbarc918d602010-05-04 16:12:42 +0000957 Tmp[Base.size()] = 'w';
Chris Lattnerce4a3352010-09-06 22:11:18 +0000958 MatchResultTy MatchW = MatchInstructionImpl(Operands, Inst, WErrorInfo);
Daniel Dunbarc918d602010-05-04 16:12:42 +0000959 Tmp[Base.size()] = 'l';
Chris Lattnerce4a3352010-09-06 22:11:18 +0000960 MatchResultTy MatchL = MatchInstructionImpl(Operands, Inst, LErrorInfo);
Daniel Dunbar04814492010-05-12 00:54:20 +0000961 Tmp[Base.size()] = 'q';
Chris Lattnerce4a3352010-09-06 22:11:18 +0000962 MatchResultTy MatchQ = MatchInstructionImpl(Operands, Inst, QErrorInfo);
Daniel Dunbarc918d602010-05-04 16:12:42 +0000963
964 // Restore the old token.
965 Op->setTokenValue(Base);
966
967 // If exactly one matched, then we treat that as a successful match (and the
968 // instruction will already have been filled in correctly, since the failing
969 // matches won't have modified it).
Chris Lattnerec6789f2010-09-06 20:08:02 +0000970 unsigned NumSuccessfulMatches =
971 (MatchB == Match_Success) + (MatchW == Match_Success) +
972 (MatchL == Match_Success) + (MatchQ == Match_Success);
973 if (NumSuccessfulMatches == 1)
Daniel Dunbarc918d602010-05-04 16:12:42 +0000974 return false;
975
Chris Lattnerec6789f2010-09-06 20:08:02 +0000976 // Otherwise, the match failed, try to produce a decent error message.
Daniel Dunbarf1e29d42010-08-12 00:55:38 +0000977
Daniel Dunbar09062b12010-08-12 00:55:42 +0000978 // If we had multiple suffix matches, then identify this as an ambiguous
979 // match.
Chris Lattnerec6789f2010-09-06 20:08:02 +0000980 if (NumSuccessfulMatches > 1) {
Daniel Dunbar09062b12010-08-12 00:55:42 +0000981 char MatchChars[4];
982 unsigned NumMatches = 0;
Chris Lattnerec6789f2010-09-06 20:08:02 +0000983 if (MatchB == Match_Success)
Daniel Dunbar09062b12010-08-12 00:55:42 +0000984 MatchChars[NumMatches++] = 'b';
Chris Lattnerec6789f2010-09-06 20:08:02 +0000985 if (MatchW == Match_Success)
Daniel Dunbar09062b12010-08-12 00:55:42 +0000986 MatchChars[NumMatches++] = 'w';
Chris Lattnerec6789f2010-09-06 20:08:02 +0000987 if (MatchL == Match_Success)
Daniel Dunbar09062b12010-08-12 00:55:42 +0000988 MatchChars[NumMatches++] = 'l';
Chris Lattnerec6789f2010-09-06 20:08:02 +0000989 if (MatchQ == Match_Success)
Daniel Dunbar09062b12010-08-12 00:55:42 +0000990 MatchChars[NumMatches++] = 'q';
991
992 SmallString<126> Msg;
993 raw_svector_ostream OS(Msg);
994 OS << "ambiguous instructions require an explicit suffix (could be ";
995 for (unsigned i = 0; i != NumMatches; ++i) {
996 if (i != 0)
997 OS << ", ";
998 if (i + 1 == NumMatches)
999 OS << "or ";
1000 OS << "'" << Base << MatchChars[i] << "'";
1001 }
1002 OS << ")";
1003 Error(IDLoc, OS.str());
Chris Lattnerec6789f2010-09-06 20:08:02 +00001004 return true;
Daniel Dunbar09062b12010-08-12 00:55:42 +00001005 }
Chris Lattnerec6789f2010-09-06 20:08:02 +00001006
Chris Lattnera008e8a2010-09-06 21:54:15 +00001007 // Okay, we know that none of the variants matched successfully.
Chris Lattnerec6789f2010-09-06 20:08:02 +00001008
Chris Lattnera008e8a2010-09-06 21:54:15 +00001009 // If all of the instructions reported an invalid mnemonic, then the original
1010 // mnemonic was invalid.
1011 if ((MatchB == Match_MnemonicFail) && (MatchW == Match_MnemonicFail) &&
1012 (MatchL == Match_MnemonicFail) && (MatchQ == Match_MnemonicFail)) {
Chris Lattnerce4a3352010-09-06 22:11:18 +00001013 if (!WasOriginallyInvalidOperand) {
Chris Lattnera008e8a2010-09-06 21:54:15 +00001014 Error(IDLoc, "invalid instruction mnemonic '" + Base + "'");
Chris Lattnerce4a3352010-09-06 22:11:18 +00001015 return true;
1016 }
1017
1018 // Recover location info for the operand if we know which was the problem.
1019 SMLoc ErrorLoc = IDLoc;
1020 if (OrigErrorInfo != ~0U) {
1021 ErrorLoc = ((X86Operand*)Operands[OrigErrorInfo])->getStartLoc();
1022 if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
1023 }
1024
1025 Error(ErrorLoc, "invalid operand for instruction");
Chris Lattnera008e8a2010-09-06 21:54:15 +00001026 return true;
1027 }
Chris Lattnerec6789f2010-09-06 20:08:02 +00001028
1029 // If one instruction matched with a missing feature, report this as a
1030 // missing feature.
1031 if ((MatchB == Match_MissingFeature) + (MatchW == Match_MissingFeature) +
Chris Lattnera008e8a2010-09-06 21:54:15 +00001032 (MatchL == Match_MissingFeature) + (MatchQ == Match_MissingFeature) == 1){
Chris Lattnerec6789f2010-09-06 20:08:02 +00001033 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1034 return true;
1035 }
1036
Chris Lattnera008e8a2010-09-06 21:54:15 +00001037 // If one instruction matched with an invalid operand, report this as an
1038 // operand failure.
1039 if ((MatchB == Match_InvalidOperand) + (MatchW == Match_InvalidOperand) +
1040 (MatchL == Match_InvalidOperand) + (MatchQ == Match_InvalidOperand) == 1){
1041 Error(IDLoc, "invalid operand for instruction");
1042 return true;
1043 }
1044
Chris Lattnerec6789f2010-09-06 20:08:02 +00001045 // If all of these were an outright failure, report it in a useless way.
1046 // FIXME: We should give nicer diagnostics about the exact failure.
Chris Lattnera008e8a2010-09-06 21:54:15 +00001047 Error(IDLoc, "unknown use of instruction mnemonic without a size suffix");
Daniel Dunbarc918d602010-05-04 16:12:42 +00001048 return true;
1049}
1050
1051
Sean Callanane88f5522010-01-23 02:43:15 +00001052extern "C" void LLVMInitializeX86AsmLexer();
1053
Daniel Dunbar092a9dd2009-07-17 20:42:00 +00001054// Force static initialization.
1055extern "C" void LLVMInitializeX86AsmParser() {
Daniel Dunbarf98bc632010-03-18 20:06:02 +00001056 RegisterAsmParser<X86_32ATTAsmParser> X(TheX86_32Target);
1057 RegisterAsmParser<X86_64ATTAsmParser> Y(TheX86_64Target);
Sean Callanane88f5522010-01-23 02:43:15 +00001058 LLVMInitializeX86AsmLexer();
Daniel Dunbar092a9dd2009-07-17 20:42:00 +00001059}
Daniel Dunbar0e2771f2009-07-29 00:02:19 +00001060
Chris Lattner0692ee62010-09-06 19:11:01 +00001061#define GET_REGISTER_MATCHER
1062#define GET_MATCHER_IMPLEMENTATION
Daniel Dunbar0e2771f2009-07-29 00:02:19 +00001063#include "X86GenAsmMatcher.inc"