X86AsmParser.cpp revision 0bb83a84d4319030c0c9260dbfea461c40eea1b2
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"
1333d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner#include "llvm/Target/TargetRegistry.h"
1433d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner#include "llvm/Target/TargetAsmParser.h"
159c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby#include "llvm/MC/MCStreamer.h"
168c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar#include "llvm/MC/MCExpr.h"
17a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar#include "llvm/MC/MCInst.h"
18c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmLexer.h"
19c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmParser.h"
20c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
2133d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner#include "llvm/ADT/SmallString.h"
2233d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner#include "llvm/ADT/SmallVector.h"
2333d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner#include "llvm/ADT/StringExtras.h"
2433d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner#include "llvm/ADT/StringSwitch.h"
2533d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner#include "llvm/ADT/Twine.h"
2616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar#include "llvm/Support/SourceMgr.h"
2709062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar#include "llvm/Support/raw_ostream.h"
28092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbarusing namespace llvm;
29092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar
30092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbarnamespace {
31c6b79ac88e52367dd2afdf03b1be81b10345c0bbBenjamin Kramerstruct X86Operand;
32092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar
3316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbarclass X86ATTAsmParser : public TargetAsmParser {
3416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  MCAsmParser &Parser;
35d73ada7d24832bc2a4c3965b8f00ffd951341acfDaniel Dunbar  TargetMachine &TM;
36a2edbabcb86f213eca6daeda5d801f8c7b1e44b2Daniel Dunbar
37f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbarprotected:
38f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar  unsigned Is64Bit : 1;
397036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner
4016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbarprivate:
4116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  MCAsmParser &getParser() const { return Parser; }
42a2edbabcb86f213eca6daeda5d801f8c7b1e44b2Daniel Dunbar
4316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
4416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
4516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
4616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
4729ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
4816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
49309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner  X86Operand *ParseOperand();
50eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner  X86Operand *ParseMemOperand(unsigned SegReg, SMLoc StartLoc);
519c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby
529c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby  bool ParseDirectiveWord(unsigned Size, SMLoc L);
539c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby
547036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner  bool MatchAndEmitInstruction(SMLoc IDLoc,
557c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner                               SmallVectorImpl<MCParsedAsmOperand*> &Operands,
567036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner                               MCStreamer &Out);
5720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
5854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  /// @name Auto-generated Matcher Functions
5954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  /// {
600692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner
610692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER
620692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "X86GenAsmMatcher.inc"
630692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner
640e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar  /// }
6516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
6616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbarpublic:
67d73ada7d24832bc2a4c3965b8f00ffd951341acfDaniel Dunbar  X86ATTAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &TM)
6854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar    : TargetAsmParser(T), Parser(_Parser), TM(TM) {
697036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner
7054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar    // Initialize the set of available features.
7154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar    setAvailableFeatures(ComputeAvailableFeatures(
7254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar                           &TM.getSubtarget<X86Subtarget>()));
7354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  }
7416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
7538e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc,
769898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner                                SmallVectorImpl<MCParsedAsmOperand*> &Operands);
779c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby
789c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby  virtual bool ParseDirective(AsmToken DirectiveID);
7916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar};
80f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
81f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbarclass X86_32ATTAsmParser : public X86ATTAsmParser {
82f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbarpublic:
83d73ada7d24832bc2a4c3965b8f00ffd951341acfDaniel Dunbar  X86_32ATTAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &TM)
84d73ada7d24832bc2a4c3965b8f00ffd951341acfDaniel Dunbar    : X86ATTAsmParser(T, _Parser, TM) {
85f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar    Is64Bit = false;
86f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar  }
87f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar};
88f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar
89f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbarclass X86_64ATTAsmParser : public X86ATTAsmParser {
90f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbarpublic:
91d73ada7d24832bc2a4c3965b8f00ffd951341acfDaniel Dunbar  X86_64ATTAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &TM)
92d73ada7d24832bc2a4c3965b8f00ffd951341acfDaniel Dunbar    : X86ATTAsmParser(T, _Parser, TM) {
93f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar    Is64Bit = true;
94f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar  }
95f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar};
96f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar
9737dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner} // end anonymous namespace
9837dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner
99e9b466d4f09de3b46c0d0d1e71cabddc7cc9021bSean Callanan/// @name Auto-generated Match Functions
100f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes/// {
101e9b466d4f09de3b46c0d0d1e71cabddc7cc9021bSean Callanan
102b8d6e98e566724f58344d275a4bd675249bb713aChris Lattnerstatic unsigned MatchRegisterName(StringRef Name);
103e9b466d4f09de3b46c0d0d1e71cabddc7cc9021bSean Callanan
104e9b466d4f09de3b46c0d0d1e71cabddc7cc9021bSean Callanan/// }
10537dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner
10637dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattnernamespace {
10716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
10816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar/// X86Operand - Instances of this class represent a parsed X86 machine
10916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar/// instruction.
11045220a84394758c86cc29ee0e3fe6738946fbcd0Chris Lattnerstruct X86Operand : public MCParsedAsmOperand {
1111f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner  enum KindTy {
11220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    Token,
11316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    Register,
11416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    Immediate,
11516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    Memory
11616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  } Kind;
11716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
11829ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner  SMLoc StartLoc, EndLoc;
119f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
12016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  union {
12116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    struct {
12220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar      const char *Data;
12320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar      unsigned Length;
12420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    } Tok;
12520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
12620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    struct {
12716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      unsigned RegNo;
12816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    } Reg;
12916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
13016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    struct {
1318c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar      const MCExpr *Val;
13216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    } Imm;
13316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
13416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    struct {
13516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      unsigned SegReg;
1368c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar      const MCExpr *Disp;
13716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      unsigned BaseReg;
13816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      unsigned IndexReg;
13916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      unsigned Scale;
14016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    } Mem;
141dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar  };
14216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
1430a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner  X86Operand(KindTy K, SMLoc Start, SMLoc End)
1441f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner    : Kind(K), StartLoc(Start), EndLoc(End) {}
145c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
1461f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner  /// getStartLoc - Get the location of the first token of this operand.
1471f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner  SMLoc getStartLoc() const { return StartLoc; }
1481f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner  /// getEndLoc - Get the location of the last token of this operand.
1491f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner  SMLoc getEndLoc() const { return EndLoc; }
1501f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner
151b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar  virtual void dump(raw_ostream &OS) const {}
152b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar
15320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  StringRef getToken() const {
15420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    assert(Kind == Token && "Invalid access!");
15520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    return StringRef(Tok.Data, Tok.Length);
15620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  }
157c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  void setTokenValue(StringRef Value) {
158c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar    assert(Kind == Token && "Invalid access!");
159c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar    Tok.Data = Value.data();
160c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar    Tok.Length = Value.size();
161c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  }
16220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
16316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  unsigned getReg() const {
16416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    assert(Kind == Register && "Invalid access!");
16516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    return Reg.RegNo;
16616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
16716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
1688c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar  const MCExpr *getImm() const {
169022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Immediate && "Invalid access!");
170022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Imm.Val;
171022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
172022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar
1738c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar  const MCExpr *getMemDisp() const {
174022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Memory && "Invalid access!");
175022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Mem.Disp;
176022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
177022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  unsigned getMemSegReg() const {
178022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Memory && "Invalid access!");
179022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Mem.SegReg;
180022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
181022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  unsigned getMemBaseReg() const {
182022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Memory && "Invalid access!");
183022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Mem.BaseReg;
184022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
185022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  unsigned getMemIndexReg() const {
186022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Memory && "Invalid access!");
187022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Mem.IndexReg;
188022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
189022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  unsigned getMemScale() const {
190022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Memory && "Invalid access!");
191022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Mem.Scale;
192022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
193022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar
194a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  bool isToken() const {return Kind == Token; }
19520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
19620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  bool isImm() const { return Kind == Immediate; }
197f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
19862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar  bool isImmSExti16i8() const {
1995fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar    if (!isImm())
2005fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar      return false;
2015fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar
20262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // If this isn't a constant expr, just assume it fits and let relaxation
20362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // handle it.
20462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
20562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    if (!CE)
20662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar      return true;
20762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar
20862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // Otherwise, check the value is in a range that makes sense for this
20962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // extension.
21062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    uint64_t Value = CE->getValue();
21162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    return ((                                  Value <= 0x000000000000007FULL)||
21262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar            (0x000000000000FF80ULL <= Value && Value <= 0x000000000000FFFFULL)||
21362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar            (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
21462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar  }
21562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar  bool isImmSExti32i8() const {
21662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    if (!isImm())
21762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar      return false;
2185fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar
21962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // If this isn't a constant expr, just assume it fits and let relaxation
22062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // handle it.
22162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
22262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    if (!CE)
22362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar      return true;
22462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar
22562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // Otherwise, check the value is in a range that makes sense for this
22662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // extension.
22762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    uint64_t Value = CE->getValue();
22862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    return ((                                  Value <= 0x000000000000007FULL)||
22962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar            (0x00000000FFFFFF80ULL <= Value && Value <= 0x00000000FFFFFFFFULL)||
23062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar            (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
2315fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar  }
23262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar  bool isImmSExti64i8() const {
2331fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar    if (!isImm())
2341fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar      return false;
2351fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar
23662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // If this isn't a constant expr, just assume it fits and let relaxation
23762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // handle it.
23862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
23962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    if (!CE)
24062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar      return true;
24162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar
24262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // Otherwise, check the value is in a range that makes sense for this
24362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // extension.
24462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    uint64_t Value = CE->getValue();
24562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    return ((                                  Value <= 0x000000000000007FULL)||
24662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar            (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
24762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar  }
24862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar  bool isImmSExti64i32() const {
24962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    if (!isImm())
25062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar      return false;
2511fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar
25262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // If this isn't a constant expr, just assume it fits and let relaxation
25362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // handle it.
25462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
25562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    if (!CE)
25662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar      return true;
25762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar
25862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // Otherwise, check the value is in a range that makes sense for this
25962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // extension.
26062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    uint64_t Value = CE->getValue();
26162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    return ((                                  Value <= 0x000000007FFFFFFFULL)||
26262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar            (0xFFFFFFFF80000000ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
2631fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar  }
2641fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar
26520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  bool isMem() const { return Kind == Memory; }
26620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
267b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  bool isAbsMem() const {
268b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
2697b9147afa7d1875353e1c1347b6b6cf71f548229Daniel Dunbar      !getMemIndexReg() && getMemScale() == 1;
270b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  }
271b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar
27220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  bool isReg() const { return Kind == Register; }
27320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
2749c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
2759c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar    // Add as immediates when possible.
2769c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
2779c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
2789c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar    else
2799c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar      Inst.addOperand(MCOperand::CreateExpr(Expr));
2809c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar  }
2819c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar
2825c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar  void addRegOperands(MCInst &Inst, unsigned N) const {
28320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    assert(N == 1 && "Invalid number of operands!");
28420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getReg()));
28520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  }
28620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
2875c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar  void addImmOperands(MCInst &Inst, unsigned N) const {
28820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    assert(N == 1 && "Invalid number of operands!");
2899c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar    addExpr(Inst, getImm());
29020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  }
29120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
2925c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar  void addMemOperands(MCInst &Inst, unsigned N) const {
293ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar    assert((N == 5) && "Invalid number of operands!");
29420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
29520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    Inst.addOperand(MCOperand::CreateImm(getMemScale()));
29620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemIndexReg()));
2979c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar    addExpr(Inst, getMemDisp());
298ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
299ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar  }
300ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar
301b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  void addAbsMemOperands(MCInst &Inst, unsigned N) const {
302b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    assert((N == 1) && "Invalid number of operands!");
303b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    Inst.addOperand(MCOperand::CreateExpr(getMemDisp()));
304b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  }
305b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar
306b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner  static X86Operand *CreateToken(StringRef Str, SMLoc Loc) {
307b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner    X86Operand *Res = new X86Operand(Token, Loc, Loc);
30829ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Tok.Data = Str.data();
30929ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Tok.Length = Str.size();
31020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    return Res;
31120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  }
31220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
31329ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner  static X86Operand *CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc) {
3141f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner    X86Operand *Res = new X86Operand(Register, StartLoc, EndLoc);
31529ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Reg.RegNo = RegNo;
31629ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    return Res;
31716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
31820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
319b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner  static X86Operand *CreateImm(const MCExpr *Val, SMLoc StartLoc, SMLoc EndLoc){
320b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner    X86Operand *Res = new X86Operand(Immediate, StartLoc, EndLoc);
32129ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Imm.Val = Val;
32229ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    return Res;
32316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
32420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
325b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  /// Create an absolute memory operand.
326b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  static X86Operand *CreateMem(const MCExpr *Disp, SMLoc StartLoc,
327b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar                               SMLoc EndLoc) {
328b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc);
329b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    Res->Mem.SegReg   = 0;
330b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    Res->Mem.Disp     = Disp;
331b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    Res->Mem.BaseReg  = 0;
332b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    Res->Mem.IndexReg = 0;
3337b9147afa7d1875353e1c1347b6b6cf71f548229Daniel Dunbar    Res->Mem.Scale    = 1;
334b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    return Res;
335b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  }
336b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar
337b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  /// Create a generalized memory operand.
338309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner  static X86Operand *CreateMem(unsigned SegReg, const MCExpr *Disp,
339309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner                               unsigned BaseReg, unsigned IndexReg,
3400a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner                               unsigned Scale, SMLoc StartLoc, SMLoc EndLoc) {
341b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    // We should never just have a displacement, that should be parsed as an
342b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    // absolute memory operand.
343c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar    assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
344c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar
345022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    // The scale should always be one of {1,2,4,8}.
346022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
34716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar           "Invalid scale!");
3480a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner    X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc);
34929ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Mem.SegReg   = SegReg;
35029ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Mem.Disp     = Disp;
35129ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Mem.BaseReg  = BaseReg;
35229ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Mem.IndexReg = IndexReg;
35329ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Mem.Scale    = Scale;
35429ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    return Res;
35516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
35616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar};
35716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
35837dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner} // end anonymous namespace.
35916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
36016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
36129ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattnerbool X86ATTAsmParser::ParseRegister(unsigned &RegNo,
36229ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner                                    SMLoc &StartLoc, SMLoc &EndLoc) {
36323075746a1418f281bc2a088ea85560bfd833599Chris Lattner  RegNo = 0;
36418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &TokPercent = Parser.getTok();
3657b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby  assert(TokPercent.is(AsmToken::Percent) && "Invalid token kind!");
36629ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner  StartLoc = TokPercent.getLoc();
367b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat percent token.
3687b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby
36918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
3700d6cd00dbe58b456d0d33663e6a36c270aad2b5aKevin Enderby  if (Tok.isNot(AsmToken::Identifier))
3710d6cd00dbe58b456d0d33663e6a36c270aad2b5aKevin Enderby    return Error(Tok.getLoc(), "invalid register name");
37216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
3730e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar  // FIXME: Validate register for the current architecture; we have to do
3740e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar  // validation later, so maybe there is no need for this here.
3757b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby  RegNo = MatchRegisterName(Tok.getString());
376f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
37733d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner  // If the match failed, try the register name as lowercase.
37833d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner  if (RegNo == 0)
37933d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner    RegNo = MatchRegisterName(LowercaseString(Tok.getString()));
38033d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner
3813c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes  // FIXME: This should be done using Requires<In32BitMode> and
3823c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes  // Requires<In64BitMode> so "eiz" usage in 64-bit instructions
3833c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes  // can be also checked.
3843c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes  if (RegNo == X86::RIZ && !Is64Bit)
3853c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes    return Error(Tok.getLoc(), "riz register in 64-bit mode only");
3863c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes
38733d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner  // Parse "%st" as "%st(0)" and "%st(1)", which is multiple tokens.
38833d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner  if (RegNo == 0 && (Tok.getString() == "st" || Tok.getString() == "ST")) {
389e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    RegNo = X86::ST0;
390e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    EndLoc = Tok.getLoc();
391e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    Parser.Lex(); // Eat 'st'
392f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
393e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    // Check to see if we have '(4)' after %st.
394e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    if (getLexer().isNot(AsmToken::LParen))
395e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner      return false;
396e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    // Lex the paren.
397e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    getParser().Lex();
398e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner
399e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    const AsmToken &IntTok = Parser.getTok();
400e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    if (IntTok.isNot(AsmToken::Integer))
401e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner      return Error(IntTok.getLoc(), "expected stack index");
402e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    switch (IntTok.getIntVal()) {
403e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 0: RegNo = X86::ST0; break;
404e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 1: RegNo = X86::ST1; break;
405e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 2: RegNo = X86::ST2; break;
406e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 3: RegNo = X86::ST3; break;
407e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 4: RegNo = X86::ST4; break;
408e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 5: RegNo = X86::ST5; break;
409e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 6: RegNo = X86::ST6; break;
410e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 7: RegNo = X86::ST7; break;
411e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    default: return Error(IntTok.getLoc(), "invalid stack index");
412e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    }
413f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
414e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    if (getParser().Lex().isNot(AsmToken::RParen))
415e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner      return Error(Parser.getTok().getLoc(), "expected ')'");
416f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
417e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    EndLoc = Tok.getLoc();
418e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    Parser.Lex(); // Eat ')'
419e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    return false;
420e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner  }
421f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
422645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner  // If this is "db[0-7]", match it as an alias
423645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner  // for dr[0-7].
424645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner  if (RegNo == 0 && Tok.getString().size() == 3 &&
425645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner      Tok.getString().startswith("db")) {
426645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    switch (Tok.getString()[2]) {
427645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '0': RegNo = X86::DR0; break;
428645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '1': RegNo = X86::DR1; break;
429645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '2': RegNo = X86::DR2; break;
430645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '3': RegNo = X86::DR3; break;
431645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '4': RegNo = X86::DR4; break;
432645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '5': RegNo = X86::DR5; break;
433645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '6': RegNo = X86::DR6; break;
434645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '7': RegNo = X86::DR7; break;
435645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    }
436f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
437645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    if (RegNo != 0) {
438645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner      EndLoc = Tok.getLoc();
439645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner      Parser.Lex(); // Eat it.
440645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner      return false;
441645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    }
442645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner  }
443f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
444245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar  if (RegNo == 0)
4450e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar    return Error(Tok.getLoc(), "invalid register name");
4460e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar
44729ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner  EndLoc = Tok.getLoc();
448b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat identifier token.
44916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  return false;
450092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar}
451092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar
452309264d1e4c41923ff04fb6786749185cf3b9de1Chris LattnerX86Operand *X86ATTAsmParser::ParseOperand() {
45316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  switch (getLexer().getKind()) {
45416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  default:
455eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    // Parse a memory operand with no segment register.
456eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    return ParseMemOperand(0, Parser.getTok().getLoc());
45723075746a1418f281bc2a088ea85560bfd833599Chris Lattner  case AsmToken::Percent: {
458eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    // Read the register.
45923075746a1418f281bc2a088ea85560bfd833599Chris Lattner    unsigned RegNo;
46029ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    SMLoc Start, End;
46129ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    if (ParseRegister(RegNo, Start, End)) return 0;
4623c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes    if (RegNo == X86::EIZ || RegNo == X86::RIZ) {
4633c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes      Error(Start, "eiz and riz can only be used as index registers");
4643c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes      return 0;
4653c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes    }
466f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
467eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    // If this is a segment register followed by a ':', then this is the start
468eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    // of a memory reference, otherwise this is a normal register reference.
469eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    if (getLexer().isNot(AsmToken::Colon))
470eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner      return X86Operand::CreateReg(RegNo, Start, End);
471f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
472f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
473eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    getParser().Lex(); // Eat the colon.
474eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    return ParseMemOperand(RegNo, Start);
47523075746a1418f281bc2a088ea85560bfd833599Chris Lattner  }
47616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  case AsmToken::Dollar: {
47716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // $42 -> immediate.
47818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    SMLoc Start = Parser.getTok().getLoc(), End;
479b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
4808c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar    const MCExpr *Val;
48154482b472a888c9efe003ad694ecf47b21878f0eChris Lattner    if (getParser().ParseExpression(Val, End))
482309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner      return 0;
483b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner    return X86Operand::CreateImm(Val, Start, End);
48416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
48516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
48616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar}
48716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
488eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner/// ParseMemOperand: segment: disp(basereg, indexreg, scale).  The '%ds:' prefix
489eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner/// has already been parsed if present.
490eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris LattnerX86Operand *X86ATTAsmParser::ParseMemOperand(unsigned SegReg, SMLoc MemStart) {
491f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
49216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  // We have to disambiguate a parenthesized expression "(4+5)" from the start
49316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)".  The
49475f265fbbbb64ab060bf41c5a4677ce56014ce9fChris Lattner  // only way to do this without lookahead is to eat the '(' and see what is
49575f265fbbbb64ab060bf41c5a4677ce56014ce9fChris Lattner  // after it.
4968c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar  const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext());
49716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  if (getLexer().isNot(AsmToken::LParen)) {
49854482b472a888c9efe003ad694ecf47b21878f0eChris Lattner    SMLoc ExprEnd;
49954482b472a888c9efe003ad694ecf47b21878f0eChris Lattner    if (getParser().ParseExpression(Disp, ExprEnd)) return 0;
500f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
50116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // After parsing the base expression we could either have a parenthesized
50216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // memory address or not.  If not, return now.  If so, eat the (.
50316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    if (getLexer().isNot(AsmToken::LParen)) {
504c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar      // Unless we have a segment register, treat this as an immediate.
505309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner      if (SegReg == 0)
506b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar        return X86Operand::CreateMem(Disp, MemStart, ExprEnd);
5070a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner      return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd);
50816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    }
509f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
51016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // Eat the '('.
511b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
51216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  } else {
51316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // Okay, we have a '('.  We don't know if this is an expression or not, but
51416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // so we have to eat the ( to see beyond it.
51518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    SMLoc LParenLoc = Parser.getTok().getLoc();
516b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat the '('.
517f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
5187b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby    if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) {
51916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // Nothing to do here, fall into the code below with the '(' part of the
52016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // memory operand consumed.
52116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    } else {
522b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner      SMLoc ExprEnd;
523f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
52416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // It must be an parenthesized expression, parse it now.
525b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner      if (getParser().ParseParenExpression(Disp, ExprEnd))
526309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        return 0;
527f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
52816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // After parsing the base expression we could either have a parenthesized
52916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // memory address or not.  If not, return now.  If so, eat the (.
53016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      if (getLexer().isNot(AsmToken::LParen)) {
531c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar        // Unless we have a segment register, treat this as an immediate.
532309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        if (SegReg == 0)
533b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar          return X86Operand::CreateMem(Disp, LParenLoc, ExprEnd);
5340a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner        return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd);
53516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      }
536f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
53716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // Eat the '('.
538b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();
53916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    }
54016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
541f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
54216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  // If we reached here, then we just ate the ( of the memory operand.  Process
54316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  // the rest of the memory operand.
544022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
545f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
54629ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner  if (getLexer().is(AsmToken::Percent)) {
54729ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    SMLoc L;
54829ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    if (ParseRegister(BaseReg, L, L)) return 0;
5493c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes    if (BaseReg == X86::EIZ || BaseReg == X86::RIZ) {
5503c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes      Error(L, "eiz and riz can only be used as index registers");
5513c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes      return 0;
5523c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes    }
55329ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner  }
554f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
55516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  if (getLexer().is(AsmToken::Comma)) {
556b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat the comma.
55716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
55816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // Following the comma we should have either an index register, or a scale
55916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // value. We don't support the later form, but we want to parse it
56016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // correctly.
56116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    //
56216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // Not that even though it would be completely consistent to support syntax
5633c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes    // like "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this.
5647b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby    if (getLexer().is(AsmToken::Percent)) {
56529ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner      SMLoc L;
56629ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner      if (ParseRegister(IndexReg, L, L)) return 0;
567f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
56816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      if (getLexer().isNot(AsmToken::RParen)) {
56916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar        // Parse the scale amount:
57016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar        //  ::= ',' [scale-expression]
571309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        if (getLexer().isNot(AsmToken::Comma)) {
57218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan          Error(Parser.getTok().getLoc(),
573309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner                "expected comma in scale expression");
574309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner          return 0;
575309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        }
576b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan        Parser.Lex(); // Eat the comma.
57716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
57816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar        if (getLexer().isNot(AsmToken::RParen)) {
57918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan          SMLoc Loc = Parser.getTok().getLoc();
58016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
58116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar          int64_t ScaleVal;
58216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar          if (getParser().ParseAbsoluteExpression(ScaleVal))
583309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner            return 0;
584f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
58516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar          // Validate the scale amount.
586309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner          if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8){
587309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner            Error(Loc, "scale factor in address must be 1, 2, 4 or 8");
588309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner            return 0;
589309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner          }
59016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar          Scale = (unsigned)ScaleVal;
59116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar        }
59216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      }
59316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    } else if (getLexer().isNot(AsmToken::RParen)) {
594ee9102587e7f6fc95de9fc5731b341eeb9bfc3caDaniel Dunbar      // A scale amount without an index is ignored.
59516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // index.
59618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan      SMLoc Loc = Parser.getTok().getLoc();
59716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
59816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      int64_t Value;
59916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      if (getParser().ParseAbsoluteExpression(Value))
600309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        return 0;
601f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
602ee9102587e7f6fc95de9fc5731b341eeb9bfc3caDaniel Dunbar      if (Value != 1)
603ee9102587e7f6fc95de9fc5731b341eeb9bfc3caDaniel Dunbar        Warning(Loc, "scale factor without index register is ignored");
604ee9102587e7f6fc95de9fc5731b341eeb9bfc3caDaniel Dunbar      Scale = 1;
60516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    }
60616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
607f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
60816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  // Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
609309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner  if (getLexer().isNot(AsmToken::RParen)) {
61018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    Error(Parser.getTok().getLoc(), "unexpected token in memory operand");
611309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner    return 0;
612309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner  }
61318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  SMLoc MemEnd = Parser.getTok().getLoc();
614b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat the ')'.
615f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
6160a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner  return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale,
6170a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner                               MemStart, MemEnd);
618dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar}
619dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar
6209898671a74d3fc924347e679c45edaa685b3fe6eChris Lattnerbool X86ATTAsmParser::
62138e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin KramerParseInstruction(StringRef Name, SMLoc NameLoc,
6229898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner                 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
6231b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar  // FIXME: Hack to recognize "sal..." and "rep..." for now. We need a way to
6241b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar  // represent alternative syntaxes in the .td file, without requiring
6251b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar  // instruction duplication.
6261b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar  StringRef PatchedName = StringSwitch<StringRef>(Name)
6271b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar    .Case("sal", "shl")
6281b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar    .Case("salb", "shlb")
6291b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar    .Case("sall", "shll")
6301b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar    .Case("salq", "shlq")
6311b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar    .Case("salw", "shlw")
6321b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar    .Case("repe", "rep")
6331b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar    .Case("repz", "rep")
6341b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar    .Case("repnz", "repne")
635ba8cea450f330145cc7764e23e5d8b1aadd5e131Chris Lattner    .Case("iret", "iretl")
636ba8e81cca281a92fe30c25a10d8990521128be39Chris Lattner    .Case("sysret", "sysretl")
637295646274276c6814d970bed86d3b4ff76ba3ee3Chris Lattner    .Case("cbw",  "cbtw")
638295646274276c6814d970bed86d3b4ff76ba3ee3Chris Lattner    .Case("cwd",  "cwtd")
639295646274276c6814d970bed86d3b4ff76ba3ee3Chris Lattner    .Case("cdq", "cltd")
640b1162fc05e09c7247be1896fd4aa4ca7e76c938cChris Lattner    .Case("cwde", "cwtl")
641b1162fc05e09c7247be1896fd4aa4ca7e76c938cChris Lattner    .Case("cdqe", "cltq")
642df967d613704d4e4f01ecce85c1846dfab4d9a1bChris Lattner    .Case("smovb", "movsb")
643df967d613704d4e4f01ecce85c1846dfab4d9a1bChris Lattner    .Case("smovw", "movsw")
644df967d613704d4e4f01ecce85c1846dfab4d9a1bChris Lattner    .Case("smovl", "movsl")
645df967d613704d4e4f01ecce85c1846dfab4d9a1bChris Lattner    .Case("smovq", "movsq")
646d68c474ec55a3dd43f9fa8ea4c89e5fae62909abChris Lattner    .Case("push", Is64Bit ? "pushq" : "pushl")
647373c458850a963ab062046529337fe976e1f944dChris Lattner    .Case("pop", Is64Bit ? "popq" : "popl")
648e5e4ff974df52aa870085904b6670c4d22ada0acDan Gohman    .Case("pushf", Is64Bit ? "pushfq" : "pushfl")
649e5e4ff974df52aa870085904b6670c4d22ada0acDan Gohman    .Case("popf",  Is64Bit ? "popfq"  : "popfl")
650dfa3c9d98260f899297c11cda2b15dc44fc4f91eChris Lattner    .Case("pushfd", "pushfl")
651dfa3c9d98260f899297c11cda2b15dc44fc4f91eChris Lattner    .Case("popfd",  "popfl")
6529d31d79493be05ab9cbf5b7fb16b52e79712eff3Kevin Enderby    .Case("retl", Is64Bit ? "retl" : "ret")
6539d31d79493be05ab9cbf5b7fb16b52e79712eff3Kevin Enderby    .Case("retq", Is64Bit ? "ret" : "retq")
654697d37a43625b8862a6d6993c6c5ee614fdc0843Chris Lattner    .Case("setz", "sete")  .Case("setnz", "setne")
655697d37a43625b8862a6d6993c6c5ee614fdc0843Chris Lattner    .Case("setc", "setb")  .Case("setna", "setbe")
656697d37a43625b8862a6d6993c6c5ee614fdc0843Chris Lattner    .Case("setnae", "setb").Case("setnb", "setae")
657697d37a43625b8862a6d6993c6c5ee614fdc0843Chris Lattner    .Case("setnbe", "seta").Case("setnc", "setae")
658697d37a43625b8862a6d6993c6c5ee614fdc0843Chris Lattner    .Case("setng", "setle").Case("setnge", "setl")
659697d37a43625b8862a6d6993c6c5ee614fdc0843Chris Lattner    .Case("setnl", "setge").Case("setnle", "setg")
660697d37a43625b8862a6d6993c6c5ee614fdc0843Chris Lattner    .Case("setpe", "setp") .Case("setpo", "setnp")
661697d37a43625b8862a6d6993c6c5ee614fdc0843Chris Lattner    .Case("jz", "je")  .Case("jnz", "jne")
662697d37a43625b8862a6d6993c6c5ee614fdc0843Chris Lattner    .Case("jc", "jb")  .Case("jna", "jbe")
663697d37a43625b8862a6d6993c6c5ee614fdc0843Chris Lattner    .Case("jnae", "jb").Case("jnb", "jae")
664697d37a43625b8862a6d6993c6c5ee614fdc0843Chris Lattner    .Case("jnbe", "ja").Case("jnc", "jae")
665697d37a43625b8862a6d6993c6c5ee614fdc0843Chris Lattner    .Case("jng", "jle").Case("jnge", "jl")
666697d37a43625b8862a6d6993c6c5ee614fdc0843Chris Lattner    .Case("jnl", "jge").Case("jnle", "jg")
667697d37a43625b8862a6d6993c6c5ee614fdc0843Chris Lattner    .Case("jpe", "jp") .Case("jpo", "jnp")
668e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    // Condition code aliases for 16-bit, 32-bit, 64-bit and unspec operands.
669e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovcw",  "cmovbw") .Case("cmovcl",  "cmovbl")
670e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovcq",  "cmovbq") .Case("cmovc",   "cmovb")
6710989d29d093c281a0d8b4f1b1ea22436249c4087Chris Lattner    .Case("cmovnaew","cmovbw") .Case("cmovnael","cmovbl")
6720989d29d093c281a0d8b4f1b1ea22436249c4087Chris Lattner    .Case("cmovnaeq","cmovbq") .Case("cmovnae", "cmovb")
673e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovnaw", "cmovbew").Case("cmovnal", "cmovbel")
674e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovnaq", "cmovbeq").Case("cmovna",  "cmovbe")
675e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovnbw", "cmovaew").Case("cmovnbl", "cmovael")
676e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovnbq", "cmovaeq").Case("cmovnb",  "cmovae")
677e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovnbew","cmovaw") .Case("cmovnbel","cmoval")
678e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovnbeq","cmovaq") .Case("cmovnbe", "cmova")
679e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovncw", "cmovaew").Case("cmovncl", "cmovael")
680e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovncq", "cmovaeq").Case("cmovnc",  "cmovae")
681e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovngw", "cmovlew").Case("cmovngl", "cmovlel")
682e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovngq", "cmovleq").Case("cmovng",  "cmovle")
683e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovnw",  "cmovgew").Case("cmovnl",  "cmovgel")
684e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovnq",  "cmovgeq").Case("cmovn",   "cmovge")
685e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovngw", "cmovlew").Case("cmovngl", "cmovlel")
686e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovngq", "cmovleq").Case("cmovng",  "cmovle")
687e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovngew","cmovlw") .Case("cmovngel","cmovll")
688e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovngeq","cmovlq") .Case("cmovnge", "cmovl")
689e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovnlw", "cmovgew").Case("cmovnll", "cmovgel")
690e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovnlq", "cmovgeq").Case("cmovnl",  "cmovge")
691e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovnlew","cmovgw") .Case("cmovnlel","cmovgl")
692e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovnleq","cmovgq") .Case("cmovnle", "cmovg")
693e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovnzw", "cmovnew").Case("cmovnzl", "cmovnel")
694e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovnzq", "cmovneq").Case("cmovnz",  "cmovne")
695e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovzw",  "cmovew") .Case("cmovzl",  "cmovel")
696e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner    .Case("cmovzq",  "cmoveq") .Case("cmovz",   "cmove")
697c2b942acf6008ac822c21722ac7ec84264d10befChris Lattner    // Floating point stack cmov aliases.
698c2b942acf6008ac822c21722ac7ec84264d10befChris Lattner    .Case("fcmovz", "fcmove")
699c2b942acf6008ac822c21722ac7ec84264d10befChris Lattner    .Case("fcmova", "fcmovnbe")
700c2b942acf6008ac822c21722ac7ec84264d10befChris Lattner    .Case("fcmovnae", "fcmovb")
701c2b942acf6008ac822c21722ac7ec84264d10befChris Lattner    .Case("fcmovna", "fcmovbe")
702c2b942acf6008ac822c21722ac7ec84264d10befChris Lattner    .Case("fcmovae", "fcmovnb")
7035e394429ab0a51af87056fbdaceeae879e651963Kevin Enderby    .Case("fwait", "wait")
70435aa94b229d516b9eb775ad4e13a8e2d03221cf9Chris Lattner    .Case("movzx", "movzb")  // FIXME: Not correct.
70535aa94b229d516b9eb775ad4e13a8e2d03221cf9Chris Lattner    .Case("fildq", "fildll")
7061b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar    .Default(Name);
70739e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar
70839e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar  // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}.
70939e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar  const MCExpr *ExtraImmOp = 0;
710428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes  if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) &&
71139e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      (PatchedName.endswith("ss") || PatchedName.endswith("sd") ||
71239e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar       PatchedName.endswith("ps") || PatchedName.endswith("pd"))) {
713428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes    bool IsVCMP = PatchedName.startswith("vcmp");
714428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes    unsigned SSECCIdx = IsVCMP ? 4 : 3;
71539e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar    unsigned SSEComparisonCode = StringSwitch<unsigned>(
716428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes      PatchedName.slice(SSECCIdx, PatchedName.size() - 2))
717cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("eq",          0)
718cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("lt",          1)
719cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("le",          2)
720cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("unord",       3)
721cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("neq",         4)
722cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("nlt",         5)
723cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("nle",         6)
724cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("ord",         7)
725cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("eq_uq",       8)
726cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("nge",         9)
727cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("ngt",      0x0A)
728cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("false",    0x0B)
729cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("neq_oq",   0x0C)
730cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("ge",       0x0D)
731cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("gt",       0x0E)
732cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("true",     0x0F)
733cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("eq_os",    0x10)
734cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("lt_oq",    0x11)
735cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("le_oq",    0x12)
736cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("unord_s",  0x13)
737cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("neq_us",   0x14)
738cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("nlt_uq",   0x15)
739cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("nle_uq",   0x16)
740cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("ord_s",    0x17)
741cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("eq_us",    0x18)
742cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("nge_uq",   0x19)
743cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("ngt_uq",   0x1A)
744cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("false_os", 0x1B)
745cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("neq_os",   0x1C)
746cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("ge_oq",    0x1D)
747cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("gt_oq",    0x1E)
748cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("true_us",  0x1F)
74939e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      .Default(~0U);
75039e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar    if (SSEComparisonCode != ~0U) {
75139e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      ExtraImmOp = MCConstantExpr::Create(SSEComparisonCode,
75239e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar                                          getParser().getContext());
75339e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      if (PatchedName.endswith("ss")) {
754428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes        PatchedName = IsVCMP ? "vcmpss" : "cmpss";
75539e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      } else if (PatchedName.endswith("sd")) {
756428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes        PatchedName = IsVCMP ? "vcmpsd" : "cmpsd";
75739e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      } else if (PatchedName.endswith("ps")) {
758428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes        PatchedName = IsVCMP ? "vcmpps" : "cmpps";
75939e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      } else {
76039e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar        assert(PatchedName.endswith("pd") && "Unexpected mnemonic!");
761428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes        PatchedName = IsVCMP ? "vcmppd" : "cmppd";
76239e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      }
76339e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar    }
76439e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar  }
765f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes
766f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes  // FIXME: Hack to recognize vpclmul<src1_quadword, src2_quadword>dq
767f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes  if (PatchedName.startswith("vpclmul")) {
768f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes    unsigned CLMULQuadWordSelect = StringSwitch<unsigned>(
769f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes      PatchedName.slice(7, PatchedName.size() - 2))
770f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes      .Case("lqlq", 0x00) // src1[63:0],   src2[63:0]
771f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes      .Case("hqlq", 0x01) // src1[127:64], src2[63:0]
772f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes      .Case("lqhq", 0x10) // src1[63:0],   src2[127:64]
773f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes      .Case("hqhq", 0x11) // src1[127:64], src2[127:64]
774f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes      .Default(~0U);
775f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes    if (CLMULQuadWordSelect != ~0U) {
776f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes      ExtraImmOp = MCConstantExpr::Create(CLMULQuadWordSelect,
777f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes                                          getParser().getContext());
778f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes      assert(PatchedName.endswith("dq") && "Unexpected mnemonic!");
779f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes      PatchedName = "vpclmulqdq";
780f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes    }
781f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes  }
7829607c40601b345c21af9de97ec03e124179efd24Chris Lattner
7831b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar  Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
78416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
78539e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar  if (ExtraImmOp)
78639e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar    Operands.push_back(X86Operand::CreateImm(ExtraImmOp, NameLoc, NameLoc));
78747ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner
7882544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner
7892544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  // Determine whether this is an instruction prefix.
7902544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  bool isPrefix =
7912544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner    PatchedName == "lock" || PatchedName == "rep" ||
7922544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner    PatchedName == "repne";
7932544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner
7942544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner
7952544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  // This does the actual operand parsing.  Don't parse any more if we have a
7962544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we
7972544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  // just want to parse the "lock" as the first instruction and the "incl" as
7982544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  // the next one.
7992544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  if (getLexer().isNot(AsmToken::EndOfStatement) && !isPrefix) {
8000db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar
8010db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar    // Parse '*' modifier.
8020db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar    if (getLexer().is(AsmToken::Star)) {
80318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan      SMLoc Loc = Parser.getTok().getLoc();
804b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner      Operands.push_back(X86Operand::CreateToken("*", Loc));
805b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex(); // Eat the star.
8060db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar    }
8070db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar
80816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // Read the first operand.
809309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner    if (X86Operand *Op = ParseOperand())
810309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner      Operands.push_back(Op);
811cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    else {
812cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      Parser.EatToEndOfStatement();
81316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      return true;
814cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    }
81539e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar
81616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    while (getLexer().is(AsmToken::Comma)) {
817b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();  // Eat the comma.
81816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
81916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // Parse and remember the operand.
820309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner      if (X86Operand *Op = ParseOperand())
821309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        Operands.push_back(Op);
822cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      else {
823cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        Parser.EatToEndOfStatement();
82416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar        return true;
825cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      }
82616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    }
8272544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner
828cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    if (getLexer().isNot(AsmToken::EndOfStatement)) {
829cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      Parser.EatToEndOfStatement();
8302544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner      return TokError("unexpected token in argument list");
831cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    }
83216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
83334e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner
8342544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  if (getLexer().is(AsmToken::EndOfStatement))
8352544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner    Parser.Lex(); // Consume the EndOfStatement
83616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
837e9e16a36d9ff355dab60e4b95673bf7a0cd27e86Chris Lattner  // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>.  Canonicalize to
838ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner  // "shift <op>".
839d5e7705a05947e60806b795880f09757e835f590Daniel Dunbar  if ((Name.startswith("shr") || Name.startswith("sar") ||
840d5e7705a05947e60806b795880f09757e835f590Daniel Dunbar       Name.startswith("shl")) &&
84147ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner      Operands.size() == 3) {
84247ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner    X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]);
84347ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner    if (Op1->isImm() && isa<MCConstantExpr>(Op1->getImm()) &&
84447ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner        cast<MCConstantExpr>(Op1->getImm())->getValue() == 1) {
84547ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner      delete Operands[1];
84647ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner      Operands.erase(Operands.begin() + 1);
84747ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner    }
848f2de13f8d7bed958538bbd9dbeb9b15ea48456ccDaniel Dunbar  }
849e9e16a36d9ff355dab60e4b95673bf7a0cd27e86Chris Lattner
850e9e16a36d9ff355dab60e4b95673bf7a0cd27e86Chris Lattner  // FIXME: Hack to handle recognize "rc[lr] <op>" -> "rcl $1, <op>".
851e9e16a36d9ff355dab60e4b95673bf7a0cd27e86Chris Lattner  if ((Name.startswith("rcl") || Name.startswith("rcr")) &&
852e9e16a36d9ff355dab60e4b95673bf7a0cd27e86Chris Lattner      Operands.size() == 2) {
853e9e16a36d9ff355dab60e4b95673bf7a0cd27e86Chris Lattner    const MCExpr *One = MCConstantExpr::Create(1, getParser().getContext());
854e9e16a36d9ff355dab60e4b95673bf7a0cd27e86Chris Lattner    Operands.push_back(X86Operand::CreateImm(One, NameLoc, NameLoc));
855e9e16a36d9ff355dab60e4b95673bf7a0cd27e86Chris Lattner    std::swap(Operands[1], Operands[2]);
856e9e16a36d9ff355dab60e4b95673bf7a0cd27e86Chris Lattner  }
857cfad564043021c7276ce19725f43bcde233fa549Chris Lattner
858cfad564043021c7276ce19725f43bcde233fa549Chris Lattner  // FIXME: Hack to handle recognize "sh[lr]d op,op" -> "shld $1, op,op".
859cfad564043021c7276ce19725f43bcde233fa549Chris Lattner  if ((Name.startswith("shld") || Name.startswith("shrd")) &&
860cfad564043021c7276ce19725f43bcde233fa549Chris Lattner      Operands.size() == 3) {
861cfad564043021c7276ce19725f43bcde233fa549Chris Lattner    const MCExpr *One = MCConstantExpr::Create(1, getParser().getContext());
862cfad564043021c7276ce19725f43bcde233fa549Chris Lattner    Operands.insert(Operands.begin()+1,
863cfad564043021c7276ce19725f43bcde233fa549Chris Lattner                    X86Operand::CreateImm(One, NameLoc, NameLoc));
864cfad564043021c7276ce19725f43bcde233fa549Chris Lattner  }
865cfad564043021c7276ce19725f43bcde233fa549Chris Lattner
866d5e7705a05947e60806b795880f09757e835f590Daniel Dunbar
867ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner  // FIXME: Hack to handle recognize "in[bwl] <op>".  Canonicalize it to
868ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner  // "inb <op>, %al".
869ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner  if ((Name == "inb" || Name == "inw" || Name == "inl") &&
870ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner      Operands.size() == 2) {
871ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner    unsigned Reg;
872ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner    if (Name[2] == 'b')
873ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner      Reg = MatchRegisterName("al");
874ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner    else if (Name[2] == 'w')
875ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner      Reg = MatchRegisterName("ax");
876ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner    else
877ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner      Reg = MatchRegisterName("eax");
878ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner    SMLoc Loc = Operands.back()->getEndLoc();
879ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner    Operands.push_back(X86Operand::CreateReg(Reg, Loc, Loc));
880ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner  }
881ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner
882ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner  // FIXME: Hack to handle recognize "out[bwl] <op>".  Canonicalize it to
883ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner  // "outb %al, <op>".
884ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner  if ((Name == "outb" || Name == "outw" || Name == "outl") &&
885ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner      Operands.size() == 2) {
886ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner    unsigned Reg;
887ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner    if (Name[3] == 'b')
888ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner      Reg = MatchRegisterName("al");
889ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner    else if (Name[3] == 'w')
890ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner      Reg = MatchRegisterName("ax");
891ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner    else
892ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner      Reg = MatchRegisterName("eax");
893ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner    SMLoc Loc = Operands.back()->getEndLoc();
894ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner    Operands.push_back(X86Operand::CreateReg(Reg, Loc, Loc));
895ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner    std::swap(Operands[1], Operands[2]);
896ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner  }
897ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner
898ef63c9a9b6f79fef91dc144db9d5f217d2b83a95Chris Lattner  // FIXME: Hack to handle "out[bwl]? %al, (%dx)" -> "outb %al, %dx".
899ef63c9a9b6f79fef91dc144db9d5f217d2b83a95Chris Lattner  if ((Name == "outb" || Name == "outw" || Name == "outl" || Name == "out") &&
900ef63c9a9b6f79fef91dc144db9d5f217d2b83a95Chris Lattner      Operands.size() == 3) {
901ef63c9a9b6f79fef91dc144db9d5f217d2b83a95Chris Lattner    X86Operand &Op = *(X86Operand*)Operands.back();
902ef63c9a9b6f79fef91dc144db9d5f217d2b83a95Chris Lattner    if (Op.isMem() && Op.Mem.SegReg == 0 &&
903ef63c9a9b6f79fef91dc144db9d5f217d2b83a95Chris Lattner        isa<MCConstantExpr>(Op.Mem.Disp) &&
904ef63c9a9b6f79fef91dc144db9d5f217d2b83a95Chris Lattner        cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
905ef63c9a9b6f79fef91dc144db9d5f217d2b83a95Chris Lattner        Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
906ef63c9a9b6f79fef91dc144db9d5f217d2b83a95Chris Lattner      SMLoc Loc = Op.getEndLoc();
907ef63c9a9b6f79fef91dc144db9d5f217d2b83a95Chris Lattner      Operands.back() = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
908ef63c9a9b6f79fef91dc144db9d5f217d2b83a95Chris Lattner      delete &Op;
909ef63c9a9b6f79fef91dc144db9d5f217d2b83a95Chris Lattner    }
910ef63c9a9b6f79fef91dc144db9d5f217d2b83a95Chris Lattner  }
911ef63c9a9b6f79fef91dc144db9d5f217d2b83a95Chris Lattner
912cf50a5390c09325a7fc41640449205eced4363f6Kevin Enderby  // FIXME: Hack to handle "f{mul*,add*,sub*,div*} $op, st(0)" the same as
913cf50a5390c09325a7fc41640449205eced4363f6Kevin Enderby  // "f{mul*,add*,sub*,div*} $op"
914cf50a5390c09325a7fc41640449205eced4363f6Kevin Enderby  if ((Name.startswith("fmul") || Name.startswith("fadd") ||
915cf50a5390c09325a7fc41640449205eced4363f6Kevin Enderby       Name.startswith("fsub") || Name.startswith("fdiv")) &&
916cf50a5390c09325a7fc41640449205eced4363f6Kevin Enderby      Operands.size() == 3 &&
917cf50a5390c09325a7fc41640449205eced4363f6Kevin Enderby      static_cast<X86Operand*>(Operands[2])->isReg() &&
918cf50a5390c09325a7fc41640449205eced4363f6Kevin Enderby      static_cast<X86Operand*>(Operands[2])->getReg() == X86::ST0) {
919cf50a5390c09325a7fc41640449205eced4363f6Kevin Enderby    delete Operands[2];
920cf50a5390c09325a7fc41640449205eced4363f6Kevin Enderby    Operands.erase(Operands.begin() + 2);
921cf50a5390c09325a7fc41640449205eced4363f6Kevin Enderby  }
922cb296ec0b689ccbcb08cedc5d3e090c0471eb393Chris Lattner
923cb296ec0b689ccbcb08cedc5d3e090c0471eb393Chris Lattner  // FIXME: Hack to handle "f{mulp,addp} st(0), $op" the same as
924a25f933396b8408ad89218bc60b0a93f130a3ea9Chris Lattner  // "f{mulp,addp} $op", since they commute.  We also allow fdivrp/fsubrp even
925a25f933396b8408ad89218bc60b0a93f130a3ea9Chris Lattner  // though they don't commute, solely because gas does support this.
926a25f933396b8408ad89218bc60b0a93f130a3ea9Chris Lattner  if ((Name=="fmulp" || Name=="faddp" || Name=="fsubrp" || Name=="fdivrp") &&
927a25f933396b8408ad89218bc60b0a93f130a3ea9Chris Lattner      Operands.size() == 3 &&
9282c5291b56358bf239bdfc675ed681c2da3eb4901Chris Lattner      static_cast<X86Operand*>(Operands[1])->isReg() &&
9292c5291b56358bf239bdfc675ed681c2da3eb4901Chris Lattner      static_cast<X86Operand*>(Operands[1])->getReg() == X86::ST0) {
9302c5291b56358bf239bdfc675ed681c2da3eb4901Chris Lattner    delete Operands[1];
9312c5291b56358bf239bdfc675ed681c2da3eb4901Chris Lattner    Operands.erase(Operands.begin() + 1);
9322c5291b56358bf239bdfc675ed681c2da3eb4901Chris Lattner  }
9332c5291b56358bf239bdfc675ed681c2da3eb4901Chris Lattner
934fba88d49e3fbb68bb84c295a9639fe94f9a8c6aaDaniel Dunbar  // FIXME: Hack to handle "imul <imm>, B" which is an alias for "imul <imm>, B,
935fba88d49e3fbb68bb84c295a9639fe94f9a8c6aaDaniel Dunbar  // B".
936ae528f65ba731e2e080822496ef36db950ffe1c1Daniel Dunbar  if (Name.startswith("imul") && Operands.size() == 3 &&
937fba88d49e3fbb68bb84c295a9639fe94f9a8c6aaDaniel Dunbar      static_cast<X86Operand*>(Operands[1])->isImm() &&
938ae528f65ba731e2e080822496ef36db950ffe1c1Daniel Dunbar      static_cast<X86Operand*>(Operands.back())->isReg()) {
939ae528f65ba731e2e080822496ef36db950ffe1c1Daniel Dunbar    X86Operand *Op = static_cast<X86Operand*>(Operands.back());
940ae528f65ba731e2e080822496ef36db950ffe1c1Daniel Dunbar    Operands.push_back(X86Operand::CreateReg(Op->getReg(), Op->getStartLoc(),
941ae528f65ba731e2e080822496ef36db950ffe1c1Daniel Dunbar                                             Op->getEndLoc()));
942ae528f65ba731e2e080822496ef36db950ffe1c1Daniel Dunbar  }
943c5cebeb3cb44a3fd0aaee956431159757ee47914Chris Lattner
944c5cebeb3cb44a3fd0aaee956431159757ee47914Chris Lattner  // 'sldt <mem>' can be encoded with either sldtw or sldtq with the same
945c5cebeb3cb44a3fd0aaee956431159757ee47914Chris Lattner  // effect (both store to a 16-bit mem).  Force to sldtw to avoid ambiguity
946c5cebeb3cb44a3fd0aaee956431159757ee47914Chris Lattner  // errors, since its encoding is the most compact.
947c5cebeb3cb44a3fd0aaee956431159757ee47914Chris Lattner  if (Name == "sldt" && Operands.size() == 2 &&
948aceeb3a4e2165e94624c3e5e2e7c93e325e951ddBenjamin Kramer      static_cast<X86Operand*>(Operands[1])->isMem()) {
949aceeb3a4e2165e94624c3e5e2e7c93e325e951ddBenjamin Kramer    delete Operands[0];
950c5cebeb3cb44a3fd0aaee956431159757ee47914Chris Lattner    Operands[0] = X86Operand::CreateToken("sldtw", NameLoc);
951aceeb3a4e2165e94624c3e5e2e7c93e325e951ddBenjamin Kramer  }
9529607c40601b345c21af9de97ec03e124179efd24Chris Lattner
9539607c40601b345c21af9de97ec03e124179efd24Chris Lattner  // The assembler accepts "xchgX <reg>, <mem>" and "xchgX <mem>, <reg>" as
9549607c40601b345c21af9de97ec03e124179efd24Chris Lattner  // synonyms.  Our tables only have the "<reg>, <mem>" form, so if we see the
9559607c40601b345c21af9de97ec03e124179efd24Chris Lattner  // other operand order, swap them.
95690b54547d9fcc381f8ec92c32756ad4da43ed9aaChris Lattner  if (Name == "xchgb" || Name == "xchgw" || Name == "xchgl" || Name == "xchgq"||
95790b54547d9fcc381f8ec92c32756ad4da43ed9aaChris Lattner      Name == "xchg")
9589607c40601b345c21af9de97ec03e124179efd24Chris Lattner    if (Operands.size() == 3 &&
9599607c40601b345c21af9de97ec03e124179efd24Chris Lattner        static_cast<X86Operand*>(Operands[1])->isMem() &&
9609607c40601b345c21af9de97ec03e124179efd24Chris Lattner        static_cast<X86Operand*>(Operands[2])->isReg()) {
9619607c40601b345c21af9de97ec03e124179efd24Chris Lattner      std::swap(Operands[1], Operands[2]);
9629607c40601b345c21af9de97ec03e124179efd24Chris Lattner    }
963ae528f65ba731e2e080822496ef36db950ffe1c1Daniel Dunbar
964c8ae35a8e8a6a39ae05b1c876afbf404e20961ffChris Lattner  // The assembler accepts "testX <reg>, <mem>" and "testX <mem>, <reg>" as
965c8ae35a8e8a6a39ae05b1c876afbf404e20961ffChris Lattner  // synonyms.  Our tables only have the "<mem>, <reg>" form, so if we see the
966c8ae35a8e8a6a39ae05b1c876afbf404e20961ffChris Lattner  // other operand order, swap them.
96790b54547d9fcc381f8ec92c32756ad4da43ed9aaChris Lattner  if (Name == "testb" || Name == "testw" || Name == "testl" || Name == "testq"||
96890b54547d9fcc381f8ec92c32756ad4da43ed9aaChris Lattner      Name == "test")
969c8ae35a8e8a6a39ae05b1c876afbf404e20961ffChris Lattner    if (Operands.size() == 3 &&
970c8ae35a8e8a6a39ae05b1c876afbf404e20961ffChris Lattner        static_cast<X86Operand*>(Operands[1])->isReg() &&
971c8ae35a8e8a6a39ae05b1c876afbf404e20961ffChris Lattner        static_cast<X86Operand*>(Operands[2])->isMem()) {
972c8ae35a8e8a6a39ae05b1c876afbf404e20961ffChris Lattner      std::swap(Operands[1], Operands[2]);
973c8ae35a8e8a6a39ae05b1c876afbf404e20961ffChris Lattner    }
974c8ae35a8e8a6a39ae05b1c876afbf404e20961ffChris Lattner
9752d592d10a57887ebe7c43a5e610f4278dd6c5d20Chris Lattner  // The assembler accepts these instructions with no operand as a synonym for
9762d592d10a57887ebe7c43a5e610f4278dd6c5d20Chris Lattner  // an instruction acting on st(1).  e.g. "fxch" -> "fxch %st(1)".
9772d592d10a57887ebe7c43a5e610f4278dd6c5d20Chris Lattner  if ((Name == "fxch" || Name == "fucom" || Name == "fucomp" ||
9782d592d10a57887ebe7c43a5e610f4278dd6c5d20Chris Lattner       Name == "faddp" || Name == "fsubp" || Name == "fsubrp" ||
9792d592d10a57887ebe7c43a5e610f4278dd6c5d20Chris Lattner       Name == "fmulp" || Name == "fdivp" || Name == "fdivrp") &&
9802d592d10a57887ebe7c43a5e610f4278dd6c5d20Chris Lattner      Operands.size() == 1) {
9812d592d10a57887ebe7c43a5e610f4278dd6c5d20Chris Lattner    Operands.push_back(X86Operand::CreateReg(MatchRegisterName("st(1)"),
9822d592d10a57887ebe7c43a5e610f4278dd6c5d20Chris Lattner                                             NameLoc, NameLoc));
9832d592d10a57887ebe7c43a5e610f4278dd6c5d20Chris Lattner  }
9842d592d10a57887ebe7c43a5e610f4278dd6c5d20Chris Lattner
9858f777a205e4523b773ba3af3bad007d93da56a9aChris Lattner  // The assembler accepts these instructions with two few operands as a synonym
9868f777a205e4523b773ba3af3bad007d93da56a9aChris Lattner  // for taking %st(1),%st(0) or X, %st(0).
9878f777a205e4523b773ba3af3bad007d93da56a9aChris Lattner  if ((Name == "fcomi" || Name == "fucomi") && Operands.size() < 3) {
9888f777a205e4523b773ba3af3bad007d93da56a9aChris Lattner    if (Operands.size() == 1)
9898f777a205e4523b773ba3af3bad007d93da56a9aChris Lattner      Operands.push_back(X86Operand::CreateReg(MatchRegisterName("st(1)"),
9908f777a205e4523b773ba3af3bad007d93da56a9aChris Lattner                                               NameLoc, NameLoc));
9918f777a205e4523b773ba3af3bad007d93da56a9aChris Lattner    Operands.push_back(X86Operand::CreateReg(MatchRegisterName("st(0)"),
9928f777a205e4523b773ba3af3bad007d93da56a9aChris Lattner                                             NameLoc, NameLoc));
9938f777a205e4523b773ba3af3bad007d93da56a9aChris Lattner  }
9942d592d10a57887ebe7c43a5e610f4278dd6c5d20Chris Lattner
99584f362d8912657bb21250a65331f797d5381e9a3Chris Lattner  // The assembler accepts various amounts of brokenness for fnstsw.
99684f362d8912657bb21250a65331f797d5381e9a3Chris Lattner  if (Name == "fnstsw") {
99784f362d8912657bb21250a65331f797d5381e9a3Chris Lattner    if (Operands.size() == 2 &&
99884f362d8912657bb21250a65331f797d5381e9a3Chris Lattner        static_cast<X86Operand*>(Operands[1])->isReg()) {
99984f362d8912657bb21250a65331f797d5381e9a3Chris Lattner      // "fnstsw al" and "fnstsw eax" -> "fnstw"
100084f362d8912657bb21250a65331f797d5381e9a3Chris Lattner      unsigned Reg = static_cast<X86Operand*>(Operands[1])->Reg.RegNo;
100184f362d8912657bb21250a65331f797d5381e9a3Chris Lattner      if (Reg == MatchRegisterName("eax") ||
100284f362d8912657bb21250a65331f797d5381e9a3Chris Lattner          Reg == MatchRegisterName("al")) {
100384f362d8912657bb21250a65331f797d5381e9a3Chris Lattner        delete Operands[1];
100484f362d8912657bb21250a65331f797d5381e9a3Chris Lattner        Operands.pop_back();
100584f362d8912657bb21250a65331f797d5381e9a3Chris Lattner      }
100684f362d8912657bb21250a65331f797d5381e9a3Chris Lattner    }
100784f362d8912657bb21250a65331f797d5381e9a3Chris Lattner
100884f362d8912657bb21250a65331f797d5381e9a3Chris Lattner    // "fnstw" -> "fnstw %ax"
100984f362d8912657bb21250a65331f797d5381e9a3Chris Lattner    if (Operands.size() == 1)
101084f362d8912657bb21250a65331f797d5381e9a3Chris Lattner      Operands.push_back(X86Operand::CreateReg(MatchRegisterName("ax"),
101184f362d8912657bb21250a65331f797d5381e9a3Chris Lattner                                               NameLoc, NameLoc));
101284f362d8912657bb21250a65331f797d5381e9a3Chris Lattner  }
101384f362d8912657bb21250a65331f797d5381e9a3Chris Lattner
1014cbb442640fdefae48edca2b4c60555a68352b553Chris Lattner  // jmp $42,$5 -> ljmp, similarly for call.
1015cbb442640fdefae48edca2b4c60555a68352b553Chris Lattner  if ((Name.startswith("call") || Name.startswith("jmp")) &&
1016cbb442640fdefae48edca2b4c60555a68352b553Chris Lattner      Operands.size() == 3 &&
1017cbb442640fdefae48edca2b4c60555a68352b553Chris Lattner      static_cast<X86Operand*>(Operands[1])->isImm() &&
1018cbb442640fdefae48edca2b4c60555a68352b553Chris Lattner      static_cast<X86Operand*>(Operands[2])->isImm()) {
1019cbb442640fdefae48edca2b4c60555a68352b553Chris Lattner    const char *NewOpName = StringSwitch<const char *>(Name)
1020cbb442640fdefae48edca2b4c60555a68352b553Chris Lattner      .Case("jmp", "ljmp")
1021cbb442640fdefae48edca2b4c60555a68352b553Chris Lattner      .Case("jmpw", "ljmpw")
1022cbb442640fdefae48edca2b4c60555a68352b553Chris Lattner      .Case("jmpl", "ljmpl")
1023cbb442640fdefae48edca2b4c60555a68352b553Chris Lattner      .Case("jmpq", "ljmpq")
1024cbb442640fdefae48edca2b4c60555a68352b553Chris Lattner      .Case("call", "lcall")
1025cbb442640fdefae48edca2b4c60555a68352b553Chris Lattner      .Case("callw", "lcallw")
1026cbb442640fdefae48edca2b4c60555a68352b553Chris Lattner      .Case("calll", "lcalll")
1027cbb442640fdefae48edca2b4c60555a68352b553Chris Lattner      .Case("callq", "lcallq")
1028cbb442640fdefae48edca2b4c60555a68352b553Chris Lattner    .Default(0);
1029cbb442640fdefae48edca2b4c60555a68352b553Chris Lattner    if (NewOpName) {
1030cbb442640fdefae48edca2b4c60555a68352b553Chris Lattner      delete Operands[0];
1031cbb442640fdefae48edca2b4c60555a68352b553Chris Lattner      Operands[0] = X86Operand::CreateToken(NewOpName, NameLoc);
1032d0bcc9a01590c60adb4d288691120c46a49a2288Chris Lattner      Name = NewOpName;
1033cbb442640fdefae48edca2b4c60555a68352b553Chris Lattner    }
1034cbb442640fdefae48edca2b4c60555a68352b553Chris Lattner  }
1035cbb442640fdefae48edca2b4c60555a68352b553Chris Lattner
1036d0bcc9a01590c60adb4d288691120c46a49a2288Chris Lattner  // lcall  and ljmp  -> lcalll and ljmpl
1037d0bcc9a01590c60adb4d288691120c46a49a2288Chris Lattner  if ((Name == "lcall" || Name == "ljmp") && Operands.size() == 3) {
1038d0bcc9a01590c60adb4d288691120c46a49a2288Chris Lattner    delete Operands[0];
1039d0bcc9a01590c60adb4d288691120c46a49a2288Chris Lattner    Operands[0] = X86Operand::CreateToken(Name == "lcall" ? "lcalll" : "ljmpl",
1040d0bcc9a01590c60adb4d288691120c46a49a2288Chris Lattner                                          NameLoc);
1041d0bcc9a01590c60adb4d288691120c46a49a2288Chris Lattner  }
1042d0bcc9a01590c60adb4d288691120c46a49a2288Chris Lattner
10431eb1b68e3a5241591bfa18d4beb0e0cf13a48ef2Chris Lattner  // call foo is not ambiguous with callw.
10441eb1b68e3a5241591bfa18d4beb0e0cf13a48ef2Chris Lattner  if (Name == "call" && Operands.size() == 2) {
10451eb1b68e3a5241591bfa18d4beb0e0cf13a48ef2Chris Lattner    const char *NewName = Is64Bit ? "callq" : "calll";
10461eb1b68e3a5241591bfa18d4beb0e0cf13a48ef2Chris Lattner    delete Operands[0];
10471eb1b68e3a5241591bfa18d4beb0e0cf13a48ef2Chris Lattner    Operands[0] = X86Operand::CreateToken(NewName, NameLoc);
10481eb1b68e3a5241591bfa18d4beb0e0cf13a48ef2Chris Lattner    Name = NewName;
10491eb1b68e3a5241591bfa18d4beb0e0cf13a48ef2Chris Lattner  }
10501eb1b68e3a5241591bfa18d4beb0e0cf13a48ef2Chris Lattner
105161129252e44067ae112dc856c64c814344b7e7c9Chris Lattner  // movsd -> movsl (when no operands are specified).
105261129252e44067ae112dc856c64c814344b7e7c9Chris Lattner  if (Name == "movsd" && Operands.size() == 1) {
105361129252e44067ae112dc856c64c814344b7e7c9Chris Lattner    delete Operands[0];
105461129252e44067ae112dc856c64c814344b7e7c9Chris Lattner    Operands[0] = X86Operand::CreateToken("movsl", NameLoc);
105561129252e44067ae112dc856c64c814344b7e7c9Chris Lattner  }
105661129252e44067ae112dc856c64c814344b7e7c9Chris Lattner
10570c289c140ee7a68e3d06b9d8ae6060758345ad4eChris Lattner  // fstp <mem> -> fstps <mem>.  Without this, we'll default to fstpl due to
10580c289c140ee7a68e3d06b9d8ae6060758345ad4eChris Lattner  // suffix searching.
10590c289c140ee7a68e3d06b9d8ae6060758345ad4eChris Lattner  if (Name == "fstp" && Operands.size() == 2 &&
10600c289c140ee7a68e3d06b9d8ae6060758345ad4eChris Lattner      static_cast<X86Operand*>(Operands[1])->isMem()) {
10610c289c140ee7a68e3d06b9d8ae6060758345ad4eChris Lattner    delete Operands[0];
10620c289c140ee7a68e3d06b9d8ae6060758345ad4eChris Lattner    Operands[0] = X86Operand::CreateToken("fstps", NameLoc);
10630c289c140ee7a68e3d06b9d8ae6060758345ad4eChris Lattner  }
10640c289c140ee7a68e3d06b9d8ae6060758345ad4eChris Lattner
1065fd8fddd830ad8322d04161f2f6bad6269a451ab2Chris Lattner
1066fd8fddd830ad8322d04161f2f6bad6269a451ab2Chris Lattner  // "clr <reg>" -> "xor <reg>, <reg>".
1067fd8fddd830ad8322d04161f2f6bad6269a451ab2Chris Lattner  if ((Name == "clrb" || Name == "clrw" || Name == "clrl" || Name == "clrq" ||
1068fd8fddd830ad8322d04161f2f6bad6269a451ab2Chris Lattner       Name == "clr") && Operands.size() == 2 &&
1069fd8fddd830ad8322d04161f2f6bad6269a451ab2Chris Lattner      static_cast<X86Operand*>(Operands[1])->isReg()) {
1070fd8fddd830ad8322d04161f2f6bad6269a451ab2Chris Lattner    unsigned RegNo = static_cast<X86Operand*>(Operands[1])->getReg();
1071fd8fddd830ad8322d04161f2f6bad6269a451ab2Chris Lattner    Operands.push_back(X86Operand::CreateReg(RegNo, NameLoc, NameLoc));
1072fd8fddd830ad8322d04161f2f6bad6269a451ab2Chris Lattner    delete Operands[0];
1073fd8fddd830ad8322d04161f2f6bad6269a451ab2Chris Lattner    Operands[0] = X86Operand::CreateToken("xor", NameLoc);
1074fd8fddd830ad8322d04161f2f6bad6269a451ab2Chris Lattner  }
1075fd8fddd830ad8322d04161f2f6bad6269a451ab2Chris Lattner
10769898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner  return false;
1077a3af370dc12f6d5100da5d614ab0a62da135569aDaniel Dunbar}
1078a3af370dc12f6d5100da5d614ab0a62da135569aDaniel Dunbar
10799c656450d65034c4cd3597fff61ef17376cff090Kevin Enderbybool X86ATTAsmParser::ParseDirective(AsmToken DirectiveID) {
10809c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby  StringRef IDVal = DirectiveID.getIdentifier();
10819c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby  if (IDVal == ".word")
10829c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby    return ParseDirectiveWord(2, DirectiveID.getLoc());
10839c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby  return true;
10849c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby}
10859c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby
10869c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby/// ParseDirectiveWord
10879c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby///  ::= .word [ expression (, expression)* ]
10889c656450d65034c4cd3597fff61ef17376cff090Kevin Enderbybool X86ATTAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
10899c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement)) {
10909c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby    for (;;) {
10919c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby      const MCExpr *Value;
10929c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby      if (getParser().ParseExpression(Value))
10939c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby        return true;
10949c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby
1095aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner      getParser().getStreamer().EmitValue(Value, Size, 0 /*addrspace*/);
10969c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby
10979c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby      if (getLexer().is(AsmToken::EndOfStatement))
10989c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby        break;
1099f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
11009c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby      // FIXME: Improve diagnostic.
11019c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby      if (getLexer().isNot(AsmToken::Comma))
11029c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby        return Error(L, "unexpected token in directive");
1103b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();
11049c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby    }
11059c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby  }
11069c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby
1107b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
11089c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby  return false;
11099c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby}
11109c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby
1111f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar
11122d592d10a57887ebe7c43a5e610f4278dd6c5d20Chris Lattnerbool X86ATTAsmParser::
11137036f8be4df8a1a830ca01afe9497b035a5647d6Chris LattnerMatchAndEmitInstruction(SMLoc IDLoc,
11147c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner                        SmallVectorImpl<MCParsedAsmOperand*> &Operands,
11157036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner                        MCStreamer &Out) {
1116f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar  assert(!Operands.empty() && "Unexpect empty operand list!");
11177c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner  X86Operand *Op = static_cast<X86Operand*>(Operands[0]);
11187c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner  assert(Op->isToken() && "Leading operand should always be a mnemonic!");
11197c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner
11207c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner  // First, handle aliases that expand to multiple instructions.
11217c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner  // FIXME: This should be replaced with a real .td file alias mechanism.
11220bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner  if (Op->getToken() == "fstsw" || Op->getToken() == "fstcw") {
11237c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner    MCInst Inst;
11247c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner    Inst.setOpcode(X86::WAIT);
11257c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner    Out.EmitInstruction(Inst);
1126f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar
11277c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner    delete Operands[0];
11280bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner    const char *Repl =
11290bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner      StringSwitch<const char*>(Op->getToken())
11300bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner        .Case("fstsw", "fnstsw")
11310bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner        .Case("fstcw", "fnstcw")
11320bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner        .Default(0);
11330bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner    assert(Repl && "Unknown wait-prefixed instruction");
11340bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner    Operands[0] = X86Operand::CreateToken(Repl, IDLoc);
11357c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner  }
11367c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner
11377c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner
1138a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  bool WasOriginallyInvalidOperand = false;
1139ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner  unsigned OrigErrorInfo;
11407036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner  MCInst Inst;
1141a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner
1142c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // First, try a direct match.
1143ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner  switch (MatchInstructionImpl(Operands, Inst, OrigErrorInfo)) {
1144ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  case Match_Success:
11457036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner    Out.EmitInstruction(Inst);
1146c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar    return false;
1147ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  case Match_MissingFeature:
1148ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1149ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    return true;
1150a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  case Match_InvalidOperand:
1151a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner    WasOriginallyInvalidOperand = true;
1152a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner    break;
1153a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  case Match_MnemonicFail:
1154ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    break;
1155ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  }
1156c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
1157c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // FIXME: Ideally, we would only attempt suffix matches for things which are
1158c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // valid prefixes, and we could just infer the right unambiguous
1159c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // type. However, that requires substantially more matcher support than the
1160c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // following hack.
11610692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner
1162c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // Change the operand to point to a temporary token.
1163c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  StringRef Base = Op->getToken();
1164f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar  SmallString<16> Tmp;
1165f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar  Tmp += Base;
1166f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar  Tmp += ' ';
1167f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar  Op->setTokenValue(Tmp.str());
1168c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
1169c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // Check for the various suffix matches.
1170c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  Tmp[Base.size()] = 'b';
1171ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner  unsigned BErrorInfo, WErrorInfo, LErrorInfo, QErrorInfo;
1172ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner  MatchResultTy MatchB = MatchInstructionImpl(Operands, Inst, BErrorInfo);
1173c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  Tmp[Base.size()] = 'w';
1174ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner  MatchResultTy MatchW = MatchInstructionImpl(Operands, Inst, WErrorInfo);
1175c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  Tmp[Base.size()] = 'l';
1176ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner  MatchResultTy MatchL = MatchInstructionImpl(Operands, Inst, LErrorInfo);
11770481449a0536311b5fefc9122ce679000540e013Daniel Dunbar  Tmp[Base.size()] = 'q';
1178ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner  MatchResultTy MatchQ = MatchInstructionImpl(Operands, Inst, QErrorInfo);
1179c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
1180c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // Restore the old token.
1181c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  Op->setTokenValue(Base);
1182c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
1183c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // If exactly one matched, then we treat that as a successful match (and the
1184c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // instruction will already have been filled in correctly, since the failing
1185c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // matches won't have modified it).
1186ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  unsigned NumSuccessfulMatches =
1187ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    (MatchB == Match_Success) + (MatchW == Match_Success) +
1188ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    (MatchL == Match_Success) + (MatchQ == Match_Success);
11897036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner  if (NumSuccessfulMatches == 1) {
11907036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner    Out.EmitInstruction(Inst);
1191c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar    return false;
11927036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner  }
1193c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
1194ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  // Otherwise, the match failed, try to produce a decent error message.
1195f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar
119609062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar  // If we had multiple suffix matches, then identify this as an ambiguous
119709062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar  // match.
1198ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  if (NumSuccessfulMatches > 1) {
119909062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    char MatchChars[4];
120009062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    unsigned NumMatches = 0;
1201ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    if (MatchB == Match_Success)
120209062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar      MatchChars[NumMatches++] = 'b';
1203ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    if (MatchW == Match_Success)
120409062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar      MatchChars[NumMatches++] = 'w';
1205ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    if (MatchL == Match_Success)
120609062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar      MatchChars[NumMatches++] = 'l';
1207ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    if (MatchQ == Match_Success)
120809062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar      MatchChars[NumMatches++] = 'q';
120909062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar
121009062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    SmallString<126> Msg;
121109062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    raw_svector_ostream OS(Msg);
121209062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    OS << "ambiguous instructions require an explicit suffix (could be ";
121309062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    for (unsigned i = 0; i != NumMatches; ++i) {
121409062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar      if (i != 0)
121509062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar        OS << ", ";
121609062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar      if (i + 1 == NumMatches)
121709062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar        OS << "or ";
121809062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar      OS << "'" << Base << MatchChars[i] << "'";
121909062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    }
122009062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    OS << ")";
122109062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    Error(IDLoc, OS.str());
1222ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    return true;
122309062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar  }
1224ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner
1225a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  // Okay, we know that none of the variants matched successfully.
1226ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner
1227a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  // If all of the instructions reported an invalid mnemonic, then the original
1228a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  // mnemonic was invalid.
1229a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  if ((MatchB == Match_MnemonicFail) && (MatchW == Match_MnemonicFail) &&
1230a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner      (MatchL == Match_MnemonicFail) && (MatchQ == Match_MnemonicFail)) {
1231ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner    if (!WasOriginallyInvalidOperand) {
1232a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner      Error(IDLoc, "invalid instruction mnemonic '" + Base + "'");
1233ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner      return true;
1234ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner    }
1235ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner
1236ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner    // Recover location info for the operand if we know which was the problem.
1237ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner    SMLoc ErrorLoc = IDLoc;
1238ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner    if (OrigErrorInfo != ~0U) {
1239f884012c93578912556de6ab89ecebab79b4ee31Chris Lattner      if (OrigErrorInfo >= Operands.size())
1240f884012c93578912556de6ab89ecebab79b4ee31Chris Lattner        return Error(IDLoc, "too few operands for instruction");
1241f884012c93578912556de6ab89ecebab79b4ee31Chris Lattner
1242ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner      ErrorLoc = ((X86Operand*)Operands[OrigErrorInfo])->getStartLoc();
1243ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner      if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
1244ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner    }
1245ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner
1246f884012c93578912556de6ab89ecebab79b4ee31Chris Lattner    return Error(ErrorLoc, "invalid operand for instruction");
1247a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  }
1248ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner
1249ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  // If one instruction matched with a missing feature, report this as a
1250ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  // missing feature.
1251ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  if ((MatchB == Match_MissingFeature) + (MatchW == Match_MissingFeature) +
1252a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner      (MatchL == Match_MissingFeature) + (MatchQ == Match_MissingFeature) == 1){
1253ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1254ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    return true;
1255ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  }
1256ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner
1257a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  // If one instruction matched with an invalid operand, report this as an
1258a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  // operand failure.
1259a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  if ((MatchB == Match_InvalidOperand) + (MatchW == Match_InvalidOperand) +
1260a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner      (MatchL == Match_InvalidOperand) + (MatchQ == Match_InvalidOperand) == 1){
1261a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner    Error(IDLoc, "invalid operand for instruction");
1262a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner    return true;
1263a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  }
1264a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner
1265ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  // If all of these were an outright failure, report it in a useless way.
1266ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  // FIXME: We should give nicer diagnostics about the exact failure.
1267a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  Error(IDLoc, "unknown use of instruction mnemonic without a size suffix");
1268c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  return true;
1269c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar}
1270c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
1271c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
1272e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callananextern "C" void LLVMInitializeX86AsmLexer();
1273e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan
1274092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar// Force static initialization.
1275092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbarextern "C" void LLVMInitializeX86AsmParser() {
1276f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar  RegisterAsmParser<X86_32ATTAsmParser> X(TheX86_32Target);
1277f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar  RegisterAsmParser<X86_64ATTAsmParser> Y(TheX86_64Target);
1278e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan  LLVMInitializeX86AsmLexer();
1279092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar}
12800e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar
12810692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER
12820692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION
12830e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar#include "X86GenAsmMatcher.inc"
1284