X86AsmParser.cpp revision 373c458850a963ab062046529337fe976e1f944d
1092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar//===-- X86AsmParser.cpp - Parse X86 assembly to MCInst instructions ------===//
2092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar//
3092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar//                     The LLVM Compiler Infrastructure
4092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar//
5092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar// This file is distributed under the University of Illinois Open Source
6092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar// License. See LICENSE.TXT for details.
7092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar//
8092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar//===----------------------------------------------------------------------===//
9092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar
109898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner#include "llvm/Target/TargetAsmParser.h"
114cb1e13769856716261a4d315f8202bd918502c3Daniel Dunbar#include "X86.h"
1254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar#include "X86Subtarget.h"
13f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar#include "llvm/ADT/SmallString.h"
14dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar#include "llvm/ADT/SmallVector.h"
151b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar#include "llvm/ADT/StringSwitch.h"
1616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar#include "llvm/ADT/Twine.h"
179c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby#include "llvm/MC/MCStreamer.h"
188c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar#include "llvm/MC/MCExpr.h"
19a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar#include "llvm/MC/MCInst.h"
20c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmLexer.h"
21c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmParser.h"
22c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
2316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar#include "llvm/Support/SourceMgr.h"
2409062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar#include "llvm/Support/raw_ostream.h"
25092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar#include "llvm/Target/TargetRegistry.h"
26092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar#include "llvm/Target/TargetAsmParser.h"
27092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbarusing namespace llvm;
28092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar
29092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbarnamespace {
30c6b79ac88e52367dd2afdf03b1be81b10345c0bbBenjamin Kramerstruct X86Operand;
31092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar
3216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbarclass X86ATTAsmParser : public TargetAsmParser {
3316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  MCAsmParser &Parser;
34d73ada7d24832bc2a4c3965b8f00ffd951341acfDaniel Dunbar  TargetMachine &TM;
35a2edbabcb86f213eca6daeda5d801f8c7b1e44b2Daniel Dunbar
36f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbarprotected:
37f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar  unsigned Is64Bit : 1;
38f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar
3916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbarprivate:
4016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  MCAsmParser &getParser() const { return Parser; }
41a2edbabcb86f213eca6daeda5d801f8c7b1e44b2Daniel Dunbar
4216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
4316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
4416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
4516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
4629ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
4716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
48309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner  X86Operand *ParseOperand();
49eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner  X86Operand *ParseMemOperand(unsigned SegReg, SMLoc StartLoc);
509c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby
519c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby  bool ParseDirectiveWord(unsigned Size, SMLoc L);
529c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby
53f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar  bool MatchInstruction(SMLoc IDLoc,
54f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar                        const SmallVectorImpl<MCParsedAsmOperand*> &Operands,
5520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar                        MCInst &Inst);
5620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
5754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  /// @name Auto-generated Matcher Functions
5854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  /// {
590692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner
600692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER
610692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "X86GenAsmMatcher.inc"
620692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner
630e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar  /// }
6416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
6516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbarpublic:
66d73ada7d24832bc2a4c3965b8f00ffd951341acfDaniel Dunbar  X86ATTAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &TM)
6754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar    : TargetAsmParser(T), Parser(_Parser), TM(TM) {
6854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar
6954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar    // Initialize the set of available features.
7054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar    setAvailableFeatures(ComputeAvailableFeatures(
7154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar                           &TM.getSubtarget<X86Subtarget>()));
7254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  }
7316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
7438e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc,
759898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner                                SmallVectorImpl<MCParsedAsmOperand*> &Operands);
769c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby
779c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby  virtual bool ParseDirective(AsmToken DirectiveID);
7816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar};
79f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
80f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbarclass X86_32ATTAsmParser : public X86ATTAsmParser {
81f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbarpublic:
82d73ada7d24832bc2a4c3965b8f00ffd951341acfDaniel Dunbar  X86_32ATTAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &TM)
83d73ada7d24832bc2a4c3965b8f00ffd951341acfDaniel Dunbar    : X86ATTAsmParser(T, _Parser, TM) {
84f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar    Is64Bit = false;
85f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar  }
86f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar};
87f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar
88f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbarclass X86_64ATTAsmParser : public X86ATTAsmParser {
89f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbarpublic:
90d73ada7d24832bc2a4c3965b8f00ffd951341acfDaniel Dunbar  X86_64ATTAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &TM)
91d73ada7d24832bc2a4c3965b8f00ffd951341acfDaniel Dunbar    : X86ATTAsmParser(T, _Parser, TM) {
92f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar    Is64Bit = true;
93f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar  }
94f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar};
95f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar
9637dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner} // end anonymous namespace
9737dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner
98e9b466d4f09de3b46c0d0d1e71cabddc7cc9021bSean Callanan/// @name Auto-generated Match Functions
99f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes/// {
100e9b466d4f09de3b46c0d0d1e71cabddc7cc9021bSean Callanan
101b8d6e98e566724f58344d275a4bd675249bb713aChris Lattnerstatic unsigned MatchRegisterName(StringRef Name);
102e9b466d4f09de3b46c0d0d1e71cabddc7cc9021bSean Callanan
103e9b466d4f09de3b46c0d0d1e71cabddc7cc9021bSean Callanan/// }
10437dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner
10537dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattnernamespace {
10616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
10716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar/// X86Operand - Instances of this class represent a parsed X86 machine
10816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar/// instruction.
10945220a84394758c86cc29ee0e3fe6738946fbcd0Chris Lattnerstruct X86Operand : public MCParsedAsmOperand {
1101f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner  enum KindTy {
11120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    Token,
11216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    Register,
11316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    Immediate,
11416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    Memory
11516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  } Kind;
11616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
11729ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner  SMLoc StartLoc, EndLoc;
118f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
11916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  union {
12016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    struct {
12120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar      const char *Data;
12220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar      unsigned Length;
12320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    } Tok;
12420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
12520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    struct {
12616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      unsigned RegNo;
12716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    } Reg;
12816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
12916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    struct {
1308c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar      const MCExpr *Val;
13116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    } Imm;
13216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
13316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    struct {
13416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      unsigned SegReg;
1358c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar      const MCExpr *Disp;
13616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      unsigned BaseReg;
13716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      unsigned IndexReg;
13816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      unsigned Scale;
13916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    } Mem;
140dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar  };
14116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
1420a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner  X86Operand(KindTy K, SMLoc Start, SMLoc End)
1431f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner    : Kind(K), StartLoc(Start), EndLoc(End) {}
144c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
1451f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner  /// getStartLoc - Get the location of the first token of this operand.
1461f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner  SMLoc getStartLoc() const { return StartLoc; }
1471f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner  /// getEndLoc - Get the location of the last token of this operand.
1481f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner  SMLoc getEndLoc() const { return EndLoc; }
1491f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner
150b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar  virtual void dump(raw_ostream &OS) const {}
151b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar
15220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  StringRef getToken() const {
15320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    assert(Kind == Token && "Invalid access!");
15420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    return StringRef(Tok.Data, Tok.Length);
15520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  }
156c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  void setTokenValue(StringRef Value) {
157c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar    assert(Kind == Token && "Invalid access!");
158c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar    Tok.Data = Value.data();
159c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar    Tok.Length = Value.size();
160c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  }
16120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
16216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  unsigned getReg() const {
16316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    assert(Kind == Register && "Invalid access!");
16416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    return Reg.RegNo;
16516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
16616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
1678c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar  const MCExpr *getImm() const {
168022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Immediate && "Invalid access!");
169022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Imm.Val;
170022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
171022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar
1728c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar  const MCExpr *getMemDisp() const {
173022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Memory && "Invalid access!");
174022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Mem.Disp;
175022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
176022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  unsigned getMemSegReg() const {
177022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Memory && "Invalid access!");
178022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Mem.SegReg;
179022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
180022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  unsigned getMemBaseReg() const {
181022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Memory && "Invalid access!");
182022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Mem.BaseReg;
183022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
184022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  unsigned getMemIndexReg() const {
185022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Memory && "Invalid access!");
186022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Mem.IndexReg;
187022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
188022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  unsigned getMemScale() const {
189022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Memory && "Invalid access!");
190022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Mem.Scale;
191022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
192022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar
193a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  bool isToken() const {return Kind == Token; }
19420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
19520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  bool isImm() const { return Kind == Immediate; }
196f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
19762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar  bool isImmSExti16i8() const {
1985fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar    if (!isImm())
1995fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar      return false;
2005fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar
20162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // If this isn't a constant expr, just assume it fits and let relaxation
20262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // handle it.
20362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
20462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    if (!CE)
20562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar      return true;
20662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar
20762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // Otherwise, check the value is in a range that makes sense for this
20862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // extension.
20962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    uint64_t Value = CE->getValue();
21062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    return ((                                  Value <= 0x000000000000007FULL)||
21162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar            (0x000000000000FF80ULL <= Value && Value <= 0x000000000000FFFFULL)||
21262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar            (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
21362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar  }
21462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar  bool isImmSExti32i8() const {
21562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    if (!isImm())
21662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar      return false;
2175fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar
21862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // If this isn't a constant expr, just assume it fits and let relaxation
21962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // handle it.
22062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
22162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    if (!CE)
22262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar      return true;
22362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar
22462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // Otherwise, check the value is in a range that makes sense for this
22562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // extension.
22662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    uint64_t Value = CE->getValue();
22762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    return ((                                  Value <= 0x000000000000007FULL)||
22862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar            (0x00000000FFFFFF80ULL <= Value && Value <= 0x00000000FFFFFFFFULL)||
22962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar            (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
2305fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar  }
23162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar  bool isImmSExti64i8() const {
2321fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar    if (!isImm())
2331fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar      return false;
2341fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar
23562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // If this isn't a constant expr, just assume it fits and let relaxation
23662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // handle it.
23762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
23862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    if (!CE)
23962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar      return true;
24062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar
24162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // Otherwise, check the value is in a range that makes sense for this
24262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // extension.
24362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    uint64_t Value = CE->getValue();
24462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    return ((                                  Value <= 0x000000000000007FULL)||
24562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar            (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
24662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar  }
24762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar  bool isImmSExti64i32() const {
24862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    if (!isImm())
24962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar      return false;
2501fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar
25162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // If this isn't a constant expr, just assume it fits and let relaxation
25262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // handle it.
25362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
25462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    if (!CE)
25562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar      return true;
25662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar
25762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // Otherwise, check the value is in a range that makes sense for this
25862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // extension.
25962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    uint64_t Value = CE->getValue();
26062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    return ((                                  Value <= 0x000000007FFFFFFFULL)||
26162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar            (0xFFFFFFFF80000000ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
2621fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar  }
2631fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar
26420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  bool isMem() const { return Kind == Memory; }
26520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
266b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  bool isAbsMem() const {
267b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
2687b9147afa7d1875353e1c1347b6b6cf71f548229Daniel Dunbar      !getMemIndexReg() && getMemScale() == 1;
269b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  }
270b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar
27120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  bool isReg() const { return Kind == Register; }
27220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
2739c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
2749c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar    // Add as immediates when possible.
2759c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
2769c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
2779c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar    else
2789c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar      Inst.addOperand(MCOperand::CreateExpr(Expr));
2799c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar  }
2809c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar
2815c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar  void addRegOperands(MCInst &Inst, unsigned N) const {
28220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    assert(N == 1 && "Invalid number of operands!");
28320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getReg()));
28420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  }
28520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
2865c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar  void addImmOperands(MCInst &Inst, unsigned N) const {
28720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    assert(N == 1 && "Invalid number of operands!");
2889c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar    addExpr(Inst, getImm());
28920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  }
29020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
2915c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar  void addMemOperands(MCInst &Inst, unsigned N) const {
292ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar    assert((N == 5) && "Invalid number of operands!");
29320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
29420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    Inst.addOperand(MCOperand::CreateImm(getMemScale()));
29520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemIndexReg()));
2969c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar    addExpr(Inst, getMemDisp());
297ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
298ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar  }
299ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar
300b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  void addAbsMemOperands(MCInst &Inst, unsigned N) const {
301b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    assert((N == 1) && "Invalid number of operands!");
302b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    Inst.addOperand(MCOperand::CreateExpr(getMemDisp()));
303b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  }
304b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar
305b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner  static X86Operand *CreateToken(StringRef Str, SMLoc Loc) {
306b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner    X86Operand *Res = new X86Operand(Token, Loc, Loc);
30729ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Tok.Data = Str.data();
30829ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Tok.Length = Str.size();
30920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    return Res;
31020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  }
31120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
31229ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner  static X86Operand *CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc) {
3131f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner    X86Operand *Res = new X86Operand(Register, StartLoc, EndLoc);
31429ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Reg.RegNo = RegNo;
31529ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    return Res;
31616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
31720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
318b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner  static X86Operand *CreateImm(const MCExpr *Val, SMLoc StartLoc, SMLoc EndLoc){
319b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner    X86Operand *Res = new X86Operand(Immediate, StartLoc, EndLoc);
32029ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Imm.Val = Val;
32129ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    return Res;
32216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
32320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
324b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  /// Create an absolute memory operand.
325b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  static X86Operand *CreateMem(const MCExpr *Disp, SMLoc StartLoc,
326b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar                               SMLoc EndLoc) {
327b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc);
328b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    Res->Mem.SegReg   = 0;
329b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    Res->Mem.Disp     = Disp;
330b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    Res->Mem.BaseReg  = 0;
331b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    Res->Mem.IndexReg = 0;
3327b9147afa7d1875353e1c1347b6b6cf71f548229Daniel Dunbar    Res->Mem.Scale    = 1;
333b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    return Res;
334b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  }
335b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar
336b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  /// Create a generalized memory operand.
337309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner  static X86Operand *CreateMem(unsigned SegReg, const MCExpr *Disp,
338309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner                               unsigned BaseReg, unsigned IndexReg,
3390a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner                               unsigned Scale, SMLoc StartLoc, SMLoc EndLoc) {
340b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    // We should never just have a displacement, that should be parsed as an
341b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    // absolute memory operand.
342c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar    assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
343c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar
344022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    // The scale should always be one of {1,2,4,8}.
345022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
34616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar           "Invalid scale!");
3470a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner    X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc);
34829ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Mem.SegReg   = SegReg;
34929ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Mem.Disp     = Disp;
35029ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Mem.BaseReg  = BaseReg;
35129ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Mem.IndexReg = IndexReg;
35229ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Mem.Scale    = Scale;
35329ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    return Res;
35416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
35516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar};
35616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
35737dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner} // end anonymous namespace.
35816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
35916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
36029ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattnerbool X86ATTAsmParser::ParseRegister(unsigned &RegNo,
36129ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner                                    SMLoc &StartLoc, SMLoc &EndLoc) {
36223075746a1418f281bc2a088ea85560bfd833599Chris Lattner  RegNo = 0;
36318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &TokPercent = Parser.getTok();
3647b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby  assert(TokPercent.is(AsmToken::Percent) && "Invalid token kind!");
36529ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner  StartLoc = TokPercent.getLoc();
366b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat percent token.
3677b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby
36818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
3690d6cd00dbe58b456d0d33663e6a36c270aad2b5aKevin Enderby  if (Tok.isNot(AsmToken::Identifier))
3700d6cd00dbe58b456d0d33663e6a36c270aad2b5aKevin Enderby    return Error(Tok.getLoc(), "invalid register name");
37116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
3720e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar  // FIXME: Validate register for the current architecture; we have to do
3730e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar  // validation later, so maybe there is no need for this here.
3747b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby  RegNo = MatchRegisterName(Tok.getString());
375f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
3763c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes  // FIXME: This should be done using Requires<In32BitMode> and
3773c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes  // Requires<In64BitMode> so "eiz" usage in 64-bit instructions
3783c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes  // can be also checked.
3793c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes  if (RegNo == X86::RIZ && !Is64Bit)
3803c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes    return Error(Tok.getLoc(), "riz register in 64-bit mode only");
3813c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes
382e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner  // Parse %st(1) and "%st" as "%st(0)"
383e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner  if (RegNo == 0 && Tok.getString() == "st") {
384e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    RegNo = X86::ST0;
385e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    EndLoc = Tok.getLoc();
386e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    Parser.Lex(); // Eat 'st'
387f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
388e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    // Check to see if we have '(4)' after %st.
389e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    if (getLexer().isNot(AsmToken::LParen))
390e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner      return false;
391e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    // Lex the paren.
392e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    getParser().Lex();
393e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner
394e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    const AsmToken &IntTok = Parser.getTok();
395e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    if (IntTok.isNot(AsmToken::Integer))
396e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner      return Error(IntTok.getLoc(), "expected stack index");
397e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    switch (IntTok.getIntVal()) {
398e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 0: RegNo = X86::ST0; break;
399e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 1: RegNo = X86::ST1; break;
400e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 2: RegNo = X86::ST2; break;
401e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 3: RegNo = X86::ST3; break;
402e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 4: RegNo = X86::ST4; break;
403e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 5: RegNo = X86::ST5; break;
404e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 6: RegNo = X86::ST6; break;
405e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 7: RegNo = X86::ST7; break;
406e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    default: return Error(IntTok.getLoc(), "invalid stack index");
407e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    }
408f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
409e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    if (getParser().Lex().isNot(AsmToken::RParen))
410e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner      return Error(Parser.getTok().getLoc(), "expected ')'");
411f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
412e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    EndLoc = Tok.getLoc();
413e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    Parser.Lex(); // Eat ')'
414e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    return false;
415e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner  }
416f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
417645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner  // If this is "db[0-7]", match it as an alias
418645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner  // for dr[0-7].
419645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner  if (RegNo == 0 && Tok.getString().size() == 3 &&
420645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner      Tok.getString().startswith("db")) {
421645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    switch (Tok.getString()[2]) {
422645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '0': RegNo = X86::DR0; break;
423645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '1': RegNo = X86::DR1; break;
424645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '2': RegNo = X86::DR2; break;
425645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '3': RegNo = X86::DR3; break;
426645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '4': RegNo = X86::DR4; break;
427645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '5': RegNo = X86::DR5; break;
428645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '6': RegNo = X86::DR6; break;
429645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '7': RegNo = X86::DR7; break;
430645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    }
431f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
432645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    if (RegNo != 0) {
433645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner      EndLoc = Tok.getLoc();
434645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner      Parser.Lex(); // Eat it.
435645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner      return false;
436645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    }
437645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner  }
438f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
439245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar  if (RegNo == 0)
4400e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar    return Error(Tok.getLoc(), "invalid register name");
4410e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar
44229ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner  EndLoc = Tok.getLoc();
443b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat identifier token.
44416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  return false;
445092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar}
446092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar
447309264d1e4c41923ff04fb6786749185cf3b9de1Chris LattnerX86Operand *X86ATTAsmParser::ParseOperand() {
44816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  switch (getLexer().getKind()) {
44916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  default:
450eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    // Parse a memory operand with no segment register.
451eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    return ParseMemOperand(0, Parser.getTok().getLoc());
45223075746a1418f281bc2a088ea85560bfd833599Chris Lattner  case AsmToken::Percent: {
453eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    // Read the register.
45423075746a1418f281bc2a088ea85560bfd833599Chris Lattner    unsigned RegNo;
45529ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    SMLoc Start, End;
45629ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    if (ParseRegister(RegNo, Start, End)) return 0;
4573c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes    if (RegNo == X86::EIZ || RegNo == X86::RIZ) {
4583c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes      Error(Start, "eiz and riz can only be used as index registers");
4593c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes      return 0;
4603c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes    }
461f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
462eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    // If this is a segment register followed by a ':', then this is the start
463eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    // of a memory reference, otherwise this is a normal register reference.
464eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    if (getLexer().isNot(AsmToken::Colon))
465eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner      return X86Operand::CreateReg(RegNo, Start, End);
466f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
467f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
468eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    getParser().Lex(); // Eat the colon.
469eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    return ParseMemOperand(RegNo, Start);
47023075746a1418f281bc2a088ea85560bfd833599Chris Lattner  }
47116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  case AsmToken::Dollar: {
47216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // $42 -> immediate.
47318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    SMLoc Start = Parser.getTok().getLoc(), End;
474b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
4758c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar    const MCExpr *Val;
47654482b472a888c9efe003ad694ecf47b21878f0eChris Lattner    if (getParser().ParseExpression(Val, End))
477309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner      return 0;
478b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner    return X86Operand::CreateImm(Val, Start, End);
47916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
48016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
48116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar}
48216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
483eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner/// ParseMemOperand: segment: disp(basereg, indexreg, scale).  The '%ds:' prefix
484eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner/// has already been parsed if present.
485eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris LattnerX86Operand *X86ATTAsmParser::ParseMemOperand(unsigned SegReg, SMLoc MemStart) {
486f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
48716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  // We have to disambiguate a parenthesized expression "(4+5)" from the start
48816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)".  The
48975f265fbbbb64ab060bf41c5a4677ce56014ce9fChris Lattner  // only way to do this without lookahead is to eat the '(' and see what is
49075f265fbbbb64ab060bf41c5a4677ce56014ce9fChris Lattner  // after it.
4918c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar  const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext());
49216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  if (getLexer().isNot(AsmToken::LParen)) {
49354482b472a888c9efe003ad694ecf47b21878f0eChris Lattner    SMLoc ExprEnd;
49454482b472a888c9efe003ad694ecf47b21878f0eChris Lattner    if (getParser().ParseExpression(Disp, ExprEnd)) return 0;
495f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
49616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // After parsing the base expression we could either have a parenthesized
49716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // memory address or not.  If not, return now.  If so, eat the (.
49816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    if (getLexer().isNot(AsmToken::LParen)) {
499c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar      // Unless we have a segment register, treat this as an immediate.
500309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner      if (SegReg == 0)
501b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar        return X86Operand::CreateMem(Disp, MemStart, ExprEnd);
5020a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner      return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd);
50316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    }
504f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
50516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // Eat the '('.
506b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
50716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  } else {
50816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // Okay, we have a '('.  We don't know if this is an expression or not, but
50916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // so we have to eat the ( to see beyond it.
51018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    SMLoc LParenLoc = Parser.getTok().getLoc();
511b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat the '('.
512f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
5137b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby    if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) {
51416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // Nothing to do here, fall into the code below with the '(' part of the
51516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // memory operand consumed.
51616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    } else {
517b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner      SMLoc ExprEnd;
518f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
51916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // It must be an parenthesized expression, parse it now.
520b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner      if (getParser().ParseParenExpression(Disp, ExprEnd))
521309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        return 0;
522f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
52316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // After parsing the base expression we could either have a parenthesized
52416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // memory address or not.  If not, return now.  If so, eat the (.
52516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      if (getLexer().isNot(AsmToken::LParen)) {
526c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar        // Unless we have a segment register, treat this as an immediate.
527309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        if (SegReg == 0)
528b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar          return X86Operand::CreateMem(Disp, LParenLoc, ExprEnd);
5290a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner        return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd);
53016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      }
531f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
53216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // Eat the '('.
533b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();
53416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    }
53516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
536f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
53716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  // If we reached here, then we just ate the ( of the memory operand.  Process
53816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  // the rest of the memory operand.
539022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
540f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
54129ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner  if (getLexer().is(AsmToken::Percent)) {
54229ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    SMLoc L;
54329ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    if (ParseRegister(BaseReg, L, L)) return 0;
5443c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes    if (BaseReg == X86::EIZ || BaseReg == X86::RIZ) {
5453c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes      Error(L, "eiz and riz can only be used as index registers");
5463c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes      return 0;
5473c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes    }
54829ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner  }
549f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
55016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  if (getLexer().is(AsmToken::Comma)) {
551b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat the comma.
55216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
55316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // Following the comma we should have either an index register, or a scale
55416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // value. We don't support the later form, but we want to parse it
55516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // correctly.
55616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    //
55716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // Not that even though it would be completely consistent to support syntax
5583c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes    // like "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this.
5597b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby    if (getLexer().is(AsmToken::Percent)) {
56029ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner      SMLoc L;
56129ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner      if (ParseRegister(IndexReg, L, L)) return 0;
562f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
56316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      if (getLexer().isNot(AsmToken::RParen)) {
56416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar        // Parse the scale amount:
56516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar        //  ::= ',' [scale-expression]
566309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        if (getLexer().isNot(AsmToken::Comma)) {
56718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan          Error(Parser.getTok().getLoc(),
568309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner                "expected comma in scale expression");
569309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner          return 0;
570309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        }
571b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan        Parser.Lex(); // Eat the comma.
57216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
57316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar        if (getLexer().isNot(AsmToken::RParen)) {
57418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan          SMLoc Loc = Parser.getTok().getLoc();
57516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
57616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar          int64_t ScaleVal;
57716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar          if (getParser().ParseAbsoluteExpression(ScaleVal))
578309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner            return 0;
579f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
58016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar          // Validate the scale amount.
581309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner          if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8){
582309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner            Error(Loc, "scale factor in address must be 1, 2, 4 or 8");
583309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner            return 0;
584309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner          }
58516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar          Scale = (unsigned)ScaleVal;
58616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar        }
58716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      }
58816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    } else if (getLexer().isNot(AsmToken::RParen)) {
589ee9102587e7f6fc95de9fc5731b341eeb9bfc3caDaniel Dunbar      // A scale amount without an index is ignored.
59016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // index.
59118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan      SMLoc Loc = Parser.getTok().getLoc();
59216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
59316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      int64_t Value;
59416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      if (getParser().ParseAbsoluteExpression(Value))
595309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        return 0;
596f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
597ee9102587e7f6fc95de9fc5731b341eeb9bfc3caDaniel Dunbar      if (Value != 1)
598ee9102587e7f6fc95de9fc5731b341eeb9bfc3caDaniel Dunbar        Warning(Loc, "scale factor without index register is ignored");
599ee9102587e7f6fc95de9fc5731b341eeb9bfc3caDaniel Dunbar      Scale = 1;
60016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    }
60116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
602f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
60316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  // Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
604309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner  if (getLexer().isNot(AsmToken::RParen)) {
60518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    Error(Parser.getTok().getLoc(), "unexpected token in memory operand");
606309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner    return 0;
607309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner  }
60818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  SMLoc MemEnd = Parser.getTok().getLoc();
609b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat the ')'.
610f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
6110a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner  return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale,
6120a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner                               MemStart, MemEnd);
613dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar}
614dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar
6159898671a74d3fc924347e679c45edaa685b3fe6eChris Lattnerbool X86ATTAsmParser::
61638e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin KramerParseInstruction(StringRef Name, SMLoc NameLoc,
6179898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner                 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
6181b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar  // FIXME: Hack to recognize "sal..." and "rep..." for now. We need a way to
6191b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar  // represent alternative syntaxes in the .td file, without requiring
6201b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar  // instruction duplication.
6211b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar  StringRef PatchedName = StringSwitch<StringRef>(Name)
6221b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar    .Case("sal", "shl")
6231b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar    .Case("salb", "shlb")
6241b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar    .Case("sall", "shll")
6251b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar    .Case("salq", "shlq")
6261b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar    .Case("salw", "shlw")
6271b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar    .Case("repe", "rep")
6281b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar    .Case("repz", "rep")
6291b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar    .Case("repnz", "repne")
630ba8cea450f330145cc7764e23e5d8b1aadd5e131Chris Lattner    .Case("iret", "iretl")
631ba8e81cca281a92fe30c25a10d8990521128be39Chris Lattner    .Case("sysret", "sysretl")
632d68c474ec55a3dd43f9fa8ea4c89e5fae62909abChris Lattner    .Case("push", Is64Bit ? "pushq" : "pushl")
633373c458850a963ab062046529337fe976e1f944dChris Lattner    .Case("pop", Is64Bit ? "popq" : "popl")
634e5e4ff974df52aa870085904b6670c4d22ada0acDan Gohman    .Case("pushf", Is64Bit ? "pushfq" : "pushfl")
635e5e4ff974df52aa870085904b6670c4d22ada0acDan Gohman    .Case("popf",  Is64Bit ? "popfq"  : "popfl")
6369d31d79493be05ab9cbf5b7fb16b52e79712eff3Kevin Enderby    .Case("retl", Is64Bit ? "retl" : "ret")
6379d31d79493be05ab9cbf5b7fb16b52e79712eff3Kevin Enderby    .Case("retq", Is64Bit ? "ret" : "retq")
6384c361972fd9110eff30145abdd17f195404a4e49Daniel Dunbar    .Case("setz", "sete")
6394c361972fd9110eff30145abdd17f195404a4e49Daniel Dunbar    .Case("setnz", "setne")
6404c361972fd9110eff30145abdd17f195404a4e49Daniel Dunbar    .Case("jz", "je")
6414c361972fd9110eff30145abdd17f195404a4e49Daniel Dunbar    .Case("jnz", "jne")
642bd658918df63f43654ce3b1045c7b563df91a63fKevin Enderby    .Case("jc", "jb")
643bd658918df63f43654ce3b1045c7b563df91a63fKevin Enderby    .Case("jna", "jbe")
644bd658918df63f43654ce3b1045c7b563df91a63fKevin Enderby    .Case("jnae", "jb")
645bd658918df63f43654ce3b1045c7b563df91a63fKevin Enderby    .Case("jnb", "jae")
646bd658918df63f43654ce3b1045c7b563df91a63fKevin Enderby    .Case("jnbe", "ja")
647bd658918df63f43654ce3b1045c7b563df91a63fKevin Enderby    .Case("jnc", "jae")
648bd658918df63f43654ce3b1045c7b563df91a63fKevin Enderby    .Case("jng", "jle")
649bd658918df63f43654ce3b1045c7b563df91a63fKevin Enderby    .Case("jnge", "jl")
650bd658918df63f43654ce3b1045c7b563df91a63fKevin Enderby    .Case("jnl", "jge")
651bd658918df63f43654ce3b1045c7b563df91a63fKevin Enderby    .Case("jnle", "jg")
652bd658918df63f43654ce3b1045c7b563df91a63fKevin Enderby    .Case("jpe", "jp")
653bd658918df63f43654ce3b1045c7b563df91a63fKevin Enderby    .Case("jpo", "jnp")
654e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    // Condition code aliases for 16-bit, 32-bit, 64-bit and unspec operands.
655e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovcw",  "cmovbw") .Case("cmovcl",  "cmovbl")
656e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovcq",  "cmovbq") .Case("cmovc",   "cmovb")
657e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovnaw", "cmovbew").Case("cmovnal", "cmovbel")
658e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovnaq", "cmovbeq").Case("cmovna",  "cmovbe")
659e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovnbw", "cmovaew").Case("cmovnbl", "cmovael")
660e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovnbq", "cmovaeq").Case("cmovnb",  "cmovae")
661e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovnbew","cmovaw") .Case("cmovnbel","cmoval")
662e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovnbeq","cmovaq") .Case("cmovnbe", "cmova")
663e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovncw", "cmovaew").Case("cmovncl", "cmovael")
664e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovncq", "cmovaeq").Case("cmovnc",  "cmovae")
665e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovngw", "cmovlew").Case("cmovngl", "cmovlel")
666e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovngq", "cmovleq").Case("cmovng",  "cmovle")
667e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovnw",  "cmovgew").Case("cmovnl",  "cmovgel")
668e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovnq",  "cmovgeq").Case("cmovn",   "cmovge")
669e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovngw", "cmovlew").Case("cmovngl", "cmovlel")
670e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovngq", "cmovleq").Case("cmovng",  "cmovle")
671e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovngew","cmovlw") .Case("cmovngel","cmovll")
672e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovngeq","cmovlq") .Case("cmovnge", "cmovl")
673e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovnlw", "cmovgew").Case("cmovnll", "cmovgel")
674e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovnlq", "cmovgeq").Case("cmovnl",  "cmovge")
675e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovnlew","cmovgw") .Case("cmovnlel","cmovgl")
676e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovnleq","cmovgq") .Case("cmovnle", "cmovg")
677e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovnzw", "cmovnew").Case("cmovnzl", "cmovnel")
678e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovnzq", "cmovneq").Case("cmovnz",  "cmovne")
679e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovzw",  "cmovew") .Case("cmovzl",  "cmovel")
680e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovzq",  "cmoveq") .Case("cmovz",   "cmove")
6815e394429ab0a51af87056fbdaceeae879e651963Kevin Enderby    .Case("fwait", "wait")
68231cc9655b681c1b9b0a199131588377ce578ec0dKevin Enderby    .Case("movzx", "movzb")
6831b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar    .Default(Name);
68439e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar
68539e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar  // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}.
68639e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar  const MCExpr *ExtraImmOp = 0;
687428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes  if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) &&
68839e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      (PatchedName.endswith("ss") || PatchedName.endswith("sd") ||
68939e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar       PatchedName.endswith("ps") || PatchedName.endswith("pd"))) {
690428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes    bool IsVCMP = PatchedName.startswith("vcmp");
691428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes    unsigned SSECCIdx = IsVCMP ? 4 : 3;
69239e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar    unsigned SSEComparisonCode = StringSwitch<unsigned>(
693428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes      PatchedName.slice(SSECCIdx, PatchedName.size() - 2))
694cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("eq",          0)
695cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("lt",          1)
696cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("le",          2)
697cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("unord",       3)
698cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("neq",         4)
699cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("nlt",         5)
700cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("nle",         6)
701cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("ord",         7)
702cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("eq_uq",       8)
703cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("nge",         9)
704cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("ngt",      0x0A)
705cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("false",    0x0B)
706cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("neq_oq",   0x0C)
707cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("ge",       0x0D)
708cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("gt",       0x0E)
709cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("true",     0x0F)
710cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("eq_os",    0x10)
711cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("lt_oq",    0x11)
712cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("le_oq",    0x12)
713cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("unord_s",  0x13)
714cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("neq_us",   0x14)
715cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("nlt_uq",   0x15)
716cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("nle_uq",   0x16)
717cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("ord_s",    0x17)
718cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("eq_us",    0x18)
719cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("nge_uq",   0x19)
720cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("ngt_uq",   0x1A)
721cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("false_os", 0x1B)
722cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("neq_os",   0x1C)
723cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("ge_oq",    0x1D)
724cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("gt_oq",    0x1E)
725cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("true_us",  0x1F)
72639e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      .Default(~0U);
72739e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar    if (SSEComparisonCode != ~0U) {
72839e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      ExtraImmOp = MCConstantExpr::Create(SSEComparisonCode,
72939e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar                                          getParser().getContext());
73039e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      if (PatchedName.endswith("ss")) {
731428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes        PatchedName = IsVCMP ? "vcmpss" : "cmpss";
73239e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      } else if (PatchedName.endswith("sd")) {
733428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes        PatchedName = IsVCMP ? "vcmpsd" : "cmpsd";
73439e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      } else if (PatchedName.endswith("ps")) {
735428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes        PatchedName = IsVCMP ? "vcmpps" : "cmpps";
73639e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      } else {
73739e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar        assert(PatchedName.endswith("pd") && "Unexpected mnemonic!");
738428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes        PatchedName = IsVCMP ? "vcmppd" : "cmppd";
73939e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      }
74039e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar    }
74139e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar  }
742f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes
743f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes  // FIXME: Hack to recognize vpclmul<src1_quadword, src2_quadword>dq
744f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes  if (PatchedName.startswith("vpclmul")) {
745f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes    unsigned CLMULQuadWordSelect = StringSwitch<unsigned>(
746f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes      PatchedName.slice(7, PatchedName.size() - 2))
747f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes      .Case("lqlq", 0x00) // src1[63:0],   src2[63:0]
748f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes      .Case("hqlq", 0x01) // src1[127:64], src2[63:0]
749f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes      .Case("lqhq", 0x10) // src1[63:0],   src2[127:64]
750f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes      .Case("hqhq", 0x11) // src1[127:64], src2[127:64]
751f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes      .Default(~0U);
752f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes    if (CLMULQuadWordSelect != ~0U) {
753f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes      ExtraImmOp = MCConstantExpr::Create(CLMULQuadWordSelect,
754f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes                                          getParser().getContext());
755f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes      assert(PatchedName.endswith("dq") && "Unexpected mnemonic!");
756f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes      PatchedName = "vpclmulqdq";
757f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes    }
758f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes  }
7599607c40601b345c21af9de97ec03e124179efd24Chris Lattner
7601b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar  Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
76116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
76239e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar  if (ExtraImmOp)
76339e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar    Operands.push_back(X86Operand::CreateImm(ExtraImmOp, NameLoc, NameLoc));
76447ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner
7652544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner
7662544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  // Determine whether this is an instruction prefix.
7672544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  bool isPrefix =
7682544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner    PatchedName == "lock" || PatchedName == "rep" ||
7692544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner    PatchedName == "repne";
7702544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner
7712544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner
7722544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  // This does the actual operand parsing.  Don't parse any more if we have a
7732544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we
7742544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  // just want to parse the "lock" as the first instruction and the "incl" as
7752544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  // the next one.
7762544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  if (getLexer().isNot(AsmToken::EndOfStatement) && !isPrefix) {
7770db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar
7780db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar    // Parse '*' modifier.
7790db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar    if (getLexer().is(AsmToken::Star)) {
78018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan      SMLoc Loc = Parser.getTok().getLoc();
781b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner      Operands.push_back(X86Operand::CreateToken("*", Loc));
782b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex(); // Eat the star.
7830db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar    }
7840db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar
78516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // Read the first operand.
786309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner    if (X86Operand *Op = ParseOperand())
787309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner      Operands.push_back(Op);
788309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner    else
78916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      return true;
79039e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar
79116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    while (getLexer().is(AsmToken::Comma)) {
792b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();  // Eat the comma.
79316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
79416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // Parse and remember the operand.
795309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner      if (X86Operand *Op = ParseOperand())
796309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        Operands.push_back(Op);
797309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner      else
79816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar        return true;
79916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    }
8002544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner
8012544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner    if (getLexer().isNot(AsmToken::EndOfStatement))
8022544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner      return TokError("unexpected token in argument list");
80316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
80434e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner
8052544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  if (getLexer().is(AsmToken::EndOfStatement))
8062544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner    Parser.Lex(); // Consume the EndOfStatement
80716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
808d5e7705a05947e60806b795880f09757e835f590Daniel Dunbar  // FIXME: Hack to handle recognizing s{hr,ar,hl}? $1.
809d5e7705a05947e60806b795880f09757e835f590Daniel Dunbar  if ((Name.startswith("shr") || Name.startswith("sar") ||
810d5e7705a05947e60806b795880f09757e835f590Daniel Dunbar       Name.startswith("shl")) &&
81147ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner      Operands.size() == 3) {
81247ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner    X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]);
81347ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner    if (Op1->isImm() && isa<MCConstantExpr>(Op1->getImm()) &&
81447ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner        cast<MCConstantExpr>(Op1->getImm())->getValue() == 1) {
81547ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner      delete Operands[1];
81647ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner      Operands.erase(Operands.begin() + 1);
81747ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner    }
818f2de13f8d7bed958538bbd9dbeb9b15ea48456ccDaniel Dunbar  }
819d5e7705a05947e60806b795880f09757e835f590Daniel Dunbar
820cf50a5390c09325a7fc41640449205eced4363f6Kevin Enderby  // FIXME: Hack to handle "f{mul*,add*,sub*,div*} $op, st(0)" the same as
821cf50a5390c09325a7fc41640449205eced4363f6Kevin Enderby  // "f{mul*,add*,sub*,div*} $op"
822cf50a5390c09325a7fc41640449205eced4363f6Kevin Enderby  if ((Name.startswith("fmul") || Name.startswith("fadd") ||
823cf50a5390c09325a7fc41640449205eced4363f6Kevin Enderby       Name.startswith("fsub") || Name.startswith("fdiv")) &&
824cf50a5390c09325a7fc41640449205eced4363f6Kevin Enderby      Operands.size() == 3 &&
825cf50a5390c09325a7fc41640449205eced4363f6Kevin Enderby      static_cast<X86Operand*>(Operands[2])->isReg() &&
826cf50a5390c09325a7fc41640449205eced4363f6Kevin Enderby      static_cast<X86Operand*>(Operands[2])->getReg() == X86::ST0) {
827cf50a5390c09325a7fc41640449205eced4363f6Kevin Enderby    delete Operands[2];
828cf50a5390c09325a7fc41640449205eced4363f6Kevin Enderby    Operands.erase(Operands.begin() + 2);
829cf50a5390c09325a7fc41640449205eced4363f6Kevin Enderby  }
830cf50a5390c09325a7fc41640449205eced4363f6Kevin Enderby
831fba88d49e3fbb68bb84c295a9639fe94f9a8c6aaDaniel Dunbar  // FIXME: Hack to handle "imul <imm>, B" which is an alias for "imul <imm>, B,
832fba88d49e3fbb68bb84c295a9639fe94f9a8c6aaDaniel Dunbar  // B".
833ae528f65ba731e2e080822496ef36db950ffe1c1Daniel Dunbar  if (Name.startswith("imul") && Operands.size() == 3 &&
834fba88d49e3fbb68bb84c295a9639fe94f9a8c6aaDaniel Dunbar      static_cast<X86Operand*>(Operands[1])->isImm() &&
835ae528f65ba731e2e080822496ef36db950ffe1c1Daniel Dunbar      static_cast<X86Operand*>(Operands.back())->isReg()) {
836ae528f65ba731e2e080822496ef36db950ffe1c1Daniel Dunbar    X86Operand *Op = static_cast<X86Operand*>(Operands.back());
837ae528f65ba731e2e080822496ef36db950ffe1c1Daniel Dunbar    Operands.push_back(X86Operand::CreateReg(Op->getReg(), Op->getStartLoc(),
838ae528f65ba731e2e080822496ef36db950ffe1c1Daniel Dunbar                                             Op->getEndLoc()));
839ae528f65ba731e2e080822496ef36db950ffe1c1Daniel Dunbar  }
840c5cebeb3cb44a3fd0aaee956431159757ee47914Chris Lattner
841c5cebeb3cb44a3fd0aaee956431159757ee47914Chris Lattner  // 'sldt <mem>' can be encoded with either sldtw or sldtq with the same
842c5cebeb3cb44a3fd0aaee956431159757ee47914Chris Lattner  // effect (both store to a 16-bit mem).  Force to sldtw to avoid ambiguity
843c5cebeb3cb44a3fd0aaee956431159757ee47914Chris Lattner  // errors, since its encoding is the most compact.
844c5cebeb3cb44a3fd0aaee956431159757ee47914Chris Lattner  if (Name == "sldt" && Operands.size() == 2 &&
845aceeb3a4e2165e94624c3e5e2e7c93e325e951ddBenjamin Kramer      static_cast<X86Operand*>(Operands[1])->isMem()) {
846aceeb3a4e2165e94624c3e5e2e7c93e325e951ddBenjamin Kramer    delete Operands[0];
847c5cebeb3cb44a3fd0aaee956431159757ee47914Chris Lattner    Operands[0] = X86Operand::CreateToken("sldtw", NameLoc);
848aceeb3a4e2165e94624c3e5e2e7c93e325e951ddBenjamin Kramer  }
8499607c40601b345c21af9de97ec03e124179efd24Chris Lattner
8509607c40601b345c21af9de97ec03e124179efd24Chris Lattner  // The assembler accepts "xchgX <reg>, <mem>" and "xchgX <mem>, <reg>" as
8519607c40601b345c21af9de97ec03e124179efd24Chris Lattner  // synonyms.  Our tables only have the "<reg>, <mem>" form, so if we see the
8529607c40601b345c21af9de97ec03e124179efd24Chris Lattner  // other operand order, swap them.
8539607c40601b345c21af9de97ec03e124179efd24Chris Lattner  if (Name == "xchgb" || Name == "xchgw" || Name == "xchgl" || Name == "xchgq")
8549607c40601b345c21af9de97ec03e124179efd24Chris Lattner    if (Operands.size() == 3 &&
8559607c40601b345c21af9de97ec03e124179efd24Chris Lattner        static_cast<X86Operand*>(Operands[1])->isMem() &&
8569607c40601b345c21af9de97ec03e124179efd24Chris Lattner        static_cast<X86Operand*>(Operands[2])->isReg()) {
8579607c40601b345c21af9de97ec03e124179efd24Chris Lattner      std::swap(Operands[1], Operands[2]);
8589607c40601b345c21af9de97ec03e124179efd24Chris Lattner    }
859ae528f65ba731e2e080822496ef36db950ffe1c1Daniel Dunbar
860c8ae35a8e8a6a39ae05b1c876afbf404e20961ffChris Lattner  // The assembler accepts "testX <reg>, <mem>" and "testX <mem>, <reg>" as
861c8ae35a8e8a6a39ae05b1c876afbf404e20961ffChris Lattner  // synonyms.  Our tables only have the "<mem>, <reg>" form, so if we see the
862c8ae35a8e8a6a39ae05b1c876afbf404e20961ffChris Lattner  // other operand order, swap them.
863c8ae35a8e8a6a39ae05b1c876afbf404e20961ffChris Lattner  if (Name == "testb" || Name == "testw" || Name == "testl" || Name == "testq")
864c8ae35a8e8a6a39ae05b1c876afbf404e20961ffChris Lattner    if (Operands.size() == 3 &&
865c8ae35a8e8a6a39ae05b1c876afbf404e20961ffChris Lattner        static_cast<X86Operand*>(Operands[1])->isReg() &&
866c8ae35a8e8a6a39ae05b1c876afbf404e20961ffChris Lattner        static_cast<X86Operand*>(Operands[2])->isMem()) {
867c8ae35a8e8a6a39ae05b1c876afbf404e20961ffChris Lattner      std::swap(Operands[1], Operands[2]);
868c8ae35a8e8a6a39ae05b1c876afbf404e20961ffChris Lattner    }
869c8ae35a8e8a6a39ae05b1c876afbf404e20961ffChris Lattner
8709898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner  return false;
871a3af370dc12f6d5100da5d614ab0a62da135569aDaniel Dunbar}
872a3af370dc12f6d5100da5d614ab0a62da135569aDaniel Dunbar
8739c656450d65034c4cd3597fff61ef17376cff090Kevin Enderbybool X86ATTAsmParser::ParseDirective(AsmToken DirectiveID) {
8749c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby  StringRef IDVal = DirectiveID.getIdentifier();
8759c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby  if (IDVal == ".word")
8769c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby    return ParseDirectiveWord(2, DirectiveID.getLoc());
8779c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby  return true;
8789c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby}
8799c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby
8809c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby/// ParseDirectiveWord
8819c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby///  ::= .word [ expression (, expression)* ]
8829c656450d65034c4cd3597fff61ef17376cff090Kevin Enderbybool X86ATTAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
8839c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement)) {
8849c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby    for (;;) {
8859c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby      const MCExpr *Value;
8869c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby      if (getParser().ParseExpression(Value))
8879c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby        return true;
8889c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby
889aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner      getParser().getStreamer().EmitValue(Value, Size, 0 /*addrspace*/);
8909c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby
8919c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby      if (getLexer().is(AsmToken::EndOfStatement))
8929c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby        break;
893f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
8949c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby      // FIXME: Improve diagnostic.
8959c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby      if (getLexer().isNot(AsmToken::Comma))
8969c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby        return Error(L, "unexpected token in directive");
897b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();
8989c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby    }
8999c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby  }
9009c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby
901b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
9029c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby  return false;
9039c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby}
9049c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby
905f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar
906c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbarbool
907f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel DunbarX86ATTAsmParser::MatchInstruction(SMLoc IDLoc,
908f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar                                  const SmallVectorImpl<MCParsedAsmOperand*>
909c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar                                    &Operands,
910c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar                                  MCInst &Inst) {
911f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar  assert(!Operands.empty() && "Unexpect empty operand list!");
912f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar
913a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  bool WasOriginallyInvalidOperand = false;
914ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner  unsigned OrigErrorInfo;
915a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner
916c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // First, try a direct match.
917ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner  switch (MatchInstructionImpl(Operands, Inst, OrigErrorInfo)) {
918ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  case Match_Success:
919c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar    return false;
920ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  case Match_MissingFeature:
921ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
922ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    return true;
923a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  case Match_InvalidOperand:
924a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner    WasOriginallyInvalidOperand = true;
925a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner    break;
926a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  case Match_MnemonicFail:
927ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    break;
928ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  }
929c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
930c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // FIXME: Ideally, we would only attempt suffix matches for things which are
931c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // valid prefixes, and we could just infer the right unambiguous
932c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // type. However, that requires substantially more matcher support than the
933c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // following hack.
934c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
9350692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner  X86Operand *Op = static_cast<X86Operand*>(Operands[0]);
9360692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner  assert(Op->isToken() && "Leading operand should always be a mnemonic!");
9370692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner
938c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // Change the operand to point to a temporary token.
939c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  StringRef Base = Op->getToken();
940f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar  SmallString<16> Tmp;
941f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar  Tmp += Base;
942f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar  Tmp += ' ';
943f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar  Op->setTokenValue(Tmp.str());
944c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
945c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // Check for the various suffix matches.
946c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  Tmp[Base.size()] = 'b';
947ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner  unsigned BErrorInfo, WErrorInfo, LErrorInfo, QErrorInfo;
948ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner  MatchResultTy MatchB = MatchInstructionImpl(Operands, Inst, BErrorInfo);
949c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  Tmp[Base.size()] = 'w';
950ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner  MatchResultTy MatchW = MatchInstructionImpl(Operands, Inst, WErrorInfo);
951c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  Tmp[Base.size()] = 'l';
952ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner  MatchResultTy MatchL = MatchInstructionImpl(Operands, Inst, LErrorInfo);
9530481449a0536311b5fefc9122ce679000540e013Daniel Dunbar  Tmp[Base.size()] = 'q';
954ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner  MatchResultTy MatchQ = MatchInstructionImpl(Operands, Inst, QErrorInfo);
955c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
956c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // Restore the old token.
957c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  Op->setTokenValue(Base);
958c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
959c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // If exactly one matched, then we treat that as a successful match (and the
960c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // instruction will already have been filled in correctly, since the failing
961c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // matches won't have modified it).
962ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  unsigned NumSuccessfulMatches =
963ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    (MatchB == Match_Success) + (MatchW == Match_Success) +
964ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    (MatchL == Match_Success) + (MatchQ == Match_Success);
965ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  if (NumSuccessfulMatches == 1)
966c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar    return false;
967c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
968ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  // Otherwise, the match failed, try to produce a decent error message.
969f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar
97009062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar  // If we had multiple suffix matches, then identify this as an ambiguous
97109062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar  // match.
972ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  if (NumSuccessfulMatches > 1) {
97309062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    char MatchChars[4];
97409062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    unsigned NumMatches = 0;
975ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    if (MatchB == Match_Success)
97609062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar      MatchChars[NumMatches++] = 'b';
977ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    if (MatchW == Match_Success)
97809062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar      MatchChars[NumMatches++] = 'w';
979ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    if (MatchL == Match_Success)
98009062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar      MatchChars[NumMatches++] = 'l';
981ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    if (MatchQ == Match_Success)
98209062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar      MatchChars[NumMatches++] = 'q';
98309062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar
98409062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    SmallString<126> Msg;
98509062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    raw_svector_ostream OS(Msg);
98609062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    OS << "ambiguous instructions require an explicit suffix (could be ";
98709062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    for (unsigned i = 0; i != NumMatches; ++i) {
98809062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar      if (i != 0)
98909062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar        OS << ", ";
99009062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar      if (i + 1 == NumMatches)
99109062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar        OS << "or ";
99209062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar      OS << "'" << Base << MatchChars[i] << "'";
99309062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    }
99409062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    OS << ")";
99509062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    Error(IDLoc, OS.str());
996ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    return true;
99709062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar  }
998ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner
999a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  // Okay, we know that none of the variants matched successfully.
1000ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner
1001a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  // If all of the instructions reported an invalid mnemonic, then the original
1002a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  // mnemonic was invalid.
1003a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  if ((MatchB == Match_MnemonicFail) && (MatchW == Match_MnemonicFail) &&
1004a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner      (MatchL == Match_MnemonicFail) && (MatchQ == Match_MnemonicFail)) {
1005ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner    if (!WasOriginallyInvalidOperand) {
1006a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner      Error(IDLoc, "invalid instruction mnemonic '" + Base + "'");
1007ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner      return true;
1008ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner    }
1009ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner
1010ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner    // Recover location info for the operand if we know which was the problem.
1011ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner    SMLoc ErrorLoc = IDLoc;
1012ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner    if (OrigErrorInfo != ~0U) {
1013ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner      ErrorLoc = ((X86Operand*)Operands[OrigErrorInfo])->getStartLoc();
1014ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner      if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
1015ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner    }
1016ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner
1017ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner    Error(ErrorLoc, "invalid operand for instruction");
1018a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner    return true;
1019a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  }
1020ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner
1021ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  // If one instruction matched with a missing feature, report this as a
1022ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  // missing feature.
1023ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  if ((MatchB == Match_MissingFeature) + (MatchW == Match_MissingFeature) +
1024a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner      (MatchL == Match_MissingFeature) + (MatchQ == Match_MissingFeature) == 1){
1025ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1026ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    return true;
1027ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  }
1028ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner
1029a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  // If one instruction matched with an invalid operand, report this as an
1030a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  // operand failure.
1031a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  if ((MatchB == Match_InvalidOperand) + (MatchW == Match_InvalidOperand) +
1032a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner      (MatchL == Match_InvalidOperand) + (MatchQ == Match_InvalidOperand) == 1){
1033a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner    Error(IDLoc, "invalid operand for instruction");
1034a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner    return true;
1035a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  }
1036a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner
1037ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  // If all of these were an outright failure, report it in a useless way.
1038ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  // FIXME: We should give nicer diagnostics about the exact failure.
1039a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  Error(IDLoc, "unknown use of instruction mnemonic without a size suffix");
1040c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  return true;
1041c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar}
1042c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
1043c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
1044e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callananextern "C" void LLVMInitializeX86AsmLexer();
1045e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan
1046092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar// Force static initialization.
1047092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbarextern "C" void LLVMInitializeX86AsmParser() {
1048f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar  RegisterAsmParser<X86_32ATTAsmParser> X(TheX86_32Target);
1049f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar  RegisterAsmParser<X86_64ATTAsmParser> Y(TheX86_64Target);
1050e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan  LLVMInitializeX86AsmLexer();
1051092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar}
10520e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar
10530692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER
10540692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION
10550e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar#include "X86GenAsmMatcher.inc"
1056