X86AsmParser.cpp revision b7f689bab98777236a2bf600f299d232d246bb61
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"
18ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng#include "llvm/MC/MCSubtargetInfo.h"
19c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmLexer.h"
20c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmParser.h"
21c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
2275ca4b94bd9dcd3952fdc237429342a2154ba142Benjamin Kramer#include "llvm/ADT/OwningPtr.h"
2333d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner#include "llvm/ADT/SmallString.h"
2433d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner#include "llvm/ADT/SmallVector.h"
2533d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner#include "llvm/ADT/StringExtras.h"
2633d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner#include "llvm/ADT/StringSwitch.h"
2733d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner#include "llvm/ADT/Twine.h"
2816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar#include "llvm/Support/SourceMgr.h"
2909062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar#include "llvm/Support/raw_ostream.h"
30ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
31ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng#define GET_SUBTARGETINFO_ENUM
32ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng#include "X86GenSubtargetInfo.inc"
33ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
34092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbarusing namespace llvm;
35092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar
36092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbarnamespace {
37c6b79ac88e52367dd2afdf03b1be81b10345c0bbBenjamin Kramerstruct X86Operand;
38092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar
3916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbarclass X86ATTAsmParser : public TargetAsmParser {
40ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  MCSubtargetInfo &STI;
4116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  MCAsmParser &Parser;
42c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
4316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbarprivate:
4416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  MCAsmParser &getParser() const { return Parser; }
45a2edbabcb86f213eca6daeda5d801f8c7b1e44b2Daniel Dunbar
4616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
4716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
4816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
4916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
50309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner  X86Operand *ParseOperand();
51eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner  X86Operand *ParseMemOperand(unsigned SegReg, SMLoc StartLoc);
529c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby
539c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby  bool ParseDirectiveWord(unsigned Size, SMLoc L);
549c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby
557036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner  bool MatchAndEmitInstruction(SMLoc IDLoc,
567c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner                               SmallVectorImpl<MCParsedAsmOperand*> &Operands,
577036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner                               MCStreamer &Out);
5820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
5996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  /// isSrcOp - Returns true if operand is either (%rsi) or %ds:%(rsi)
6096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  /// in 64bit mode or (%edi) or %es:(%edi) in 32bit mode.
6196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  bool isSrcOp(X86Operand &Op);
6296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger
6396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  /// isDstOp - Returns true if operand is either %es:(%rdi) in 64bit mode
6496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  /// or %es:(%edi) in 32bit mode.
6596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  bool isDstOp(X86Operand &Op);
6696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger
6759ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  bool is64BitMode() const {
68ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    // FIXME: Can tablegen auto-generate this?
69ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    return (STI.getFeatureBits() & X86::Mode64Bit) != 0;
70ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
71ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
7254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  /// @name Auto-generated Matcher Functions
7354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  /// {
74c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
750692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER
760692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "X86GenAsmMatcher.inc"
77c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
780e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar  /// }
7916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
8016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbarpublic:
81ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  X86ATTAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser)
82ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    : TargetAsmParser(), STI(sti), Parser(parser) {
83c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
8454074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar    // Initialize the set of available features.
85ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
8654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  }
87bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky  virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
8816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
8938e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc,
909898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner                                SmallVectorImpl<MCParsedAsmOperand*> &Operands);
919c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby
929c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby  virtual bool ParseDirective(AsmToken DirectiveID);
9316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar};
9437dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner} // end anonymous namespace
9537dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner
96e9b466d4f09de3b46c0d0d1e71cabddc7cc9021bSean Callanan/// @name Auto-generated Match Functions
97f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes/// {
98e9b466d4f09de3b46c0d0d1e71cabddc7cc9021bSean Callanan
99b8d6e98e566724f58344d275a4bd675249bb713aChris Lattnerstatic unsigned MatchRegisterName(StringRef Name);
100e9b466d4f09de3b46c0d0d1e71cabddc7cc9021bSean Callanan
101e9b466d4f09de3b46c0d0d1e71cabddc7cc9021bSean Callanan/// }
10237dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner
10337dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattnernamespace {
10416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
10516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar/// X86Operand - Instances of this class represent a parsed X86 machine
10616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar/// instruction.
10745220a84394758c86cc29ee0e3fe6738946fbcd0Chris Lattnerstruct X86Operand : public MCParsedAsmOperand {
1081f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner  enum KindTy {
10920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    Token,
11016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    Register,
11116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    Immediate,
11216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    Memory
11316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  } Kind;
11416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
11529ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner  SMLoc StartLoc, EndLoc;
116f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
11716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  union {
11816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    struct {
11920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar      const char *Data;
12020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar      unsigned Length;
12120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    } Tok;
12220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
12320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    struct {
12416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      unsigned RegNo;
12516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    } Reg;
12616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
12716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    struct {
1288c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar      const MCExpr *Val;
12916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    } Imm;
13016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
13116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    struct {
13216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      unsigned SegReg;
1338c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar      const MCExpr *Disp;
13416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      unsigned BaseReg;
13516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      unsigned IndexReg;
13616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      unsigned Scale;
13716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    } Mem;
138dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar  };
13916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
1400a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner  X86Operand(KindTy K, SMLoc Start, SMLoc End)
1411f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner    : Kind(K), StartLoc(Start), EndLoc(End) {}
142c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
1431f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner  /// getStartLoc - Get the location of the first token of this operand.
1441f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner  SMLoc getStartLoc() const { return StartLoc; }
1451f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner  /// getEndLoc - Get the location of the last token of this operand.
1461f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner  SMLoc getEndLoc() const { return EndLoc; }
1471f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner
148b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbach  virtual void print(raw_ostream &OS) const {}
149b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar
15020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  StringRef getToken() const {
15120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    assert(Kind == Token && "Invalid access!");
15220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    return StringRef(Tok.Data, Tok.Length);
15320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  }
154c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  void setTokenValue(StringRef Value) {
155c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar    assert(Kind == Token && "Invalid access!");
156c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar    Tok.Data = Value.data();
157c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar    Tok.Length = Value.size();
158c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  }
15920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
16016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  unsigned getReg() const {
16116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    assert(Kind == Register && "Invalid access!");
16216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    return Reg.RegNo;
16316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
16416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
1658c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar  const MCExpr *getImm() const {
166022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Immediate && "Invalid access!");
167022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Imm.Val;
168022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
169022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar
1708c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar  const MCExpr *getMemDisp() const {
171022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Memory && "Invalid access!");
172022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Mem.Disp;
173022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
174022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  unsigned getMemSegReg() const {
175022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Memory && "Invalid access!");
176022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Mem.SegReg;
177022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
178022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  unsigned getMemBaseReg() const {
179022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Memory && "Invalid access!");
180022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Mem.BaseReg;
181022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
182022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  unsigned getMemIndexReg() const {
183022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Memory && "Invalid access!");
184022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Mem.IndexReg;
185022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
186022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  unsigned getMemScale() const {
187022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Memory && "Invalid access!");
188022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Mem.Scale;
189022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
190022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar
191a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  bool isToken() const {return Kind == Token; }
19220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
19320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  bool isImm() const { return Kind == Immediate; }
194f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
19562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar  bool isImmSExti16i8() const {
1965fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar    if (!isImm())
1975fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar      return false;
1985fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar
19962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // If this isn't a constant expr, just assume it fits and let relaxation
20062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // handle it.
20162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
20262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    if (!CE)
20362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar      return true;
20462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar
20562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // Otherwise, check the value is in a range that makes sense for this
20662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // extension.
20762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    uint64_t Value = CE->getValue();
20862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    return ((                                  Value <= 0x000000000000007FULL)||
20962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar            (0x000000000000FF80ULL <= Value && Value <= 0x000000000000FFFFULL)||
21062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar            (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
21162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar  }
21262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar  bool isImmSExti32i8() const {
21362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    if (!isImm())
21462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar      return false;
2155fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar
21662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // If this isn't a constant expr, just assume it fits and let relaxation
21762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // handle it.
21862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
21962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    if (!CE)
22062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar      return true;
22162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar
22262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // Otherwise, check the value is in a range that makes sense for this
22362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // extension.
22462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    uint64_t Value = CE->getValue();
22562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    return ((                                  Value <= 0x000000000000007FULL)||
22662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar            (0x00000000FFFFFF80ULL <= Value && Value <= 0x00000000FFFFFFFFULL)||
22762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar            (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
2285fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar  }
22962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar  bool isImmSExti64i8() const {
2301fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar    if (!isImm())
2311fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar      return false;
2321fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar
23362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // If this isn't a constant expr, just assume it fits and let relaxation
23462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // handle it.
23562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
23662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    if (!CE)
23762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar      return true;
23862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar
23962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // Otherwise, check the value is in a range that makes sense for this
24062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // extension.
24162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    uint64_t Value = CE->getValue();
24262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    return ((                                  Value <= 0x000000000000007FULL)||
24362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar            (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
24462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar  }
24562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar  bool isImmSExti64i32() const {
24662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    if (!isImm())
24762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar      return false;
2481fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar
24962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // If this isn't a constant expr, just assume it fits and let relaxation
25062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // handle it.
25162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
25262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    if (!CE)
25362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar      return true;
25462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar
25562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // Otherwise, check the value is in a range that makes sense for this
25662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // extension.
25762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    uint64_t Value = CE->getValue();
25862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    return ((                                  Value <= 0x000000007FFFFFFFULL)||
25962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar            (0xFFFFFFFF80000000ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
2601fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar  }
2611fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar
26220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  bool isMem() const { return Kind == Memory; }
26320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
264b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  bool isAbsMem() const {
265b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
2667b9147afa7d1875353e1c1347b6b6cf71f548229Daniel Dunbar      !getMemIndexReg() && getMemScale() == 1;
267b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  }
268b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar
26920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  bool isReg() const { return Kind == Register; }
27020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
2719c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
2729c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar    // Add as immediates when possible.
2739c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
2749c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
2759c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar    else
2769c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar      Inst.addOperand(MCOperand::CreateExpr(Expr));
2779c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar  }
2789c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar
2795c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar  void addRegOperands(MCInst &Inst, unsigned N) const {
28020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    assert(N == 1 && "Invalid number of operands!");
28120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getReg()));
28220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  }
28320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
2845c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar  void addImmOperands(MCInst &Inst, unsigned N) const {
28520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    assert(N == 1 && "Invalid number of operands!");
2869c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar    addExpr(Inst, getImm());
28720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  }
28820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
2895c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar  void addMemOperands(MCInst &Inst, unsigned N) const {
290ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar    assert((N == 5) && "Invalid number of operands!");
29120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
29220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    Inst.addOperand(MCOperand::CreateImm(getMemScale()));
29320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemIndexReg()));
2949c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar    addExpr(Inst, getMemDisp());
295ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
296ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar  }
297ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar
298b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  void addAbsMemOperands(MCInst &Inst, unsigned N) const {
299b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    assert((N == 1) && "Invalid number of operands!");
300b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    Inst.addOperand(MCOperand::CreateExpr(getMemDisp()));
301b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  }
302b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar
303b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner  static X86Operand *CreateToken(StringRef Str, SMLoc Loc) {
304b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner    X86Operand *Res = new X86Operand(Token, Loc, Loc);
30529ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Tok.Data = Str.data();
30629ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Tok.Length = Str.size();
30720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    return Res;
30820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  }
30920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
31029ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner  static X86Operand *CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc) {
3111f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner    X86Operand *Res = new X86Operand(Register, StartLoc, EndLoc);
31229ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Reg.RegNo = RegNo;
31329ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    return Res;
31416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
31520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
316b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner  static X86Operand *CreateImm(const MCExpr *Val, SMLoc StartLoc, SMLoc EndLoc){
317b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner    X86Operand *Res = new X86Operand(Immediate, StartLoc, EndLoc);
31829ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Imm.Val = Val;
31929ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    return Res;
32016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
32120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
322b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  /// Create an absolute memory operand.
323b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  static X86Operand *CreateMem(const MCExpr *Disp, SMLoc StartLoc,
324b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar                               SMLoc EndLoc) {
325b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc);
326b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    Res->Mem.SegReg   = 0;
327b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    Res->Mem.Disp     = Disp;
328b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    Res->Mem.BaseReg  = 0;
329b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    Res->Mem.IndexReg = 0;
3307b9147afa7d1875353e1c1347b6b6cf71f548229Daniel Dunbar    Res->Mem.Scale    = 1;
331b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    return Res;
332b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  }
333b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar
334b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  /// Create a generalized memory operand.
335309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner  static X86Operand *CreateMem(unsigned SegReg, const MCExpr *Disp,
336309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner                               unsigned BaseReg, unsigned IndexReg,
3370a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner                               unsigned Scale, SMLoc StartLoc, SMLoc EndLoc) {
338b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    // We should never just have a displacement, that should be parsed as an
339b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    // absolute memory operand.
340c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar    assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
341c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar
342022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    // The scale should always be one of {1,2,4,8}.
343022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
34416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar           "Invalid scale!");
3450a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner    X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc);
34629ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Mem.SegReg   = SegReg;
34729ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Mem.Disp     = Disp;
34829ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Mem.BaseReg  = BaseReg;
34929ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Mem.IndexReg = IndexReg;
35029ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Mem.Scale    = Scale;
35129ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    return Res;
35216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
35316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar};
35416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
35537dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner} // end anonymous namespace.
35616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
35796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenbergerbool X86ATTAsmParser::isSrcOp(X86Operand &Op) {
35859ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  unsigned basereg = is64BitMode() ? X86::RSI : X86::ESI;
35996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger
36096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  return (Op.isMem() &&
36196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    (Op.Mem.SegReg == 0 || Op.Mem.SegReg == X86::DS) &&
36296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    isa<MCConstantExpr>(Op.Mem.Disp) &&
36396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
36496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    Op.Mem.BaseReg == basereg && Op.Mem.IndexReg == 0);
36596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger}
36696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger
36796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenbergerbool X86ATTAsmParser::isDstOp(X86Operand &Op) {
36859ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  unsigned basereg = is64BitMode() ? X86::RDI : X86::EDI;
36996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger
37096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  return Op.isMem() && Op.Mem.SegReg == X86::ES &&
37196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    isa<MCConstantExpr>(Op.Mem.Disp) &&
37296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
37396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    Op.Mem.BaseReg == basereg && Op.Mem.IndexReg == 0;
37496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger}
37516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
37629ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattnerbool X86ATTAsmParser::ParseRegister(unsigned &RegNo,
37729ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner                                    SMLoc &StartLoc, SMLoc &EndLoc) {
37823075746a1418f281bc2a088ea85560bfd833599Chris Lattner  RegNo = 0;
37918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &TokPercent = Parser.getTok();
3807b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby  assert(TokPercent.is(AsmToken::Percent) && "Invalid token kind!");
38129ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner  StartLoc = TokPercent.getLoc();
382b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat percent token.
3837b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby
38418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
3850d6cd00dbe58b456d0d33663e6a36c270aad2b5aKevin Enderby  if (Tok.isNot(AsmToken::Identifier))
3860d6cd00dbe58b456d0d33663e6a36c270aad2b5aKevin Enderby    return Error(Tok.getLoc(), "invalid register name");
38716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
3880e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar  // FIXME: Validate register for the current architecture; we have to do
3890e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar  // validation later, so maybe there is no need for this here.
3907b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby  RegNo = MatchRegisterName(Tok.getString());
391f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
39233d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner  // If the match failed, try the register name as lowercase.
39333d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner  if (RegNo == 0)
39433d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner    RegNo = MatchRegisterName(LowercaseString(Tok.getString()));
395c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
3963c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes  // FIXME: This should be done using Requires<In32BitMode> and
3973c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes  // Requires<In64BitMode> so "eiz" usage in 64-bit instructions
3983c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes  // can be also checked.
39959ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  if (RegNo == X86::RIZ && !is64BitMode())
4003c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes    return Error(Tok.getLoc(), "riz register in 64-bit mode only");
4013c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes
40233d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner  // Parse "%st" as "%st(0)" and "%st(1)", which is multiple tokens.
40333d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner  if (RegNo == 0 && (Tok.getString() == "st" || Tok.getString() == "ST")) {
404e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    RegNo = X86::ST0;
405e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    EndLoc = Tok.getLoc();
406e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    Parser.Lex(); // Eat 'st'
407f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
408e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    // Check to see if we have '(4)' after %st.
409e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    if (getLexer().isNot(AsmToken::LParen))
410e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner      return false;
411e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    // Lex the paren.
412e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    getParser().Lex();
413e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner
414e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    const AsmToken &IntTok = Parser.getTok();
415e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    if (IntTok.isNot(AsmToken::Integer))
416e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner      return Error(IntTok.getLoc(), "expected stack index");
417e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    switch (IntTok.getIntVal()) {
418e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 0: RegNo = X86::ST0; break;
419e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 1: RegNo = X86::ST1; break;
420e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 2: RegNo = X86::ST2; break;
421e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 3: RegNo = X86::ST3; break;
422e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 4: RegNo = X86::ST4; break;
423e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 5: RegNo = X86::ST5; break;
424e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 6: RegNo = X86::ST6; break;
425e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 7: RegNo = X86::ST7; break;
426e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    default: return Error(IntTok.getLoc(), "invalid stack index");
427e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    }
428f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
429e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    if (getParser().Lex().isNot(AsmToken::RParen))
430e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner      return Error(Parser.getTok().getLoc(), "expected ')'");
431f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
432e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    EndLoc = Tok.getLoc();
433e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    Parser.Lex(); // Eat ')'
434e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    return false;
435e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner  }
436f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
437645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner  // If this is "db[0-7]", match it as an alias
438645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner  // for dr[0-7].
439645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner  if (RegNo == 0 && Tok.getString().size() == 3 &&
440645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner      Tok.getString().startswith("db")) {
441645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    switch (Tok.getString()[2]) {
442645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '0': RegNo = X86::DR0; break;
443645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '1': RegNo = X86::DR1; break;
444645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '2': RegNo = X86::DR2; break;
445645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '3': RegNo = X86::DR3; break;
446645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '4': RegNo = X86::DR4; break;
447645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '5': RegNo = X86::DR5; break;
448645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '6': RegNo = X86::DR6; break;
449645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '7': RegNo = X86::DR7; break;
450645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    }
451f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
452645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    if (RegNo != 0) {
453645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner      EndLoc = Tok.getLoc();
454645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner      Parser.Lex(); // Eat it.
455645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner      return false;
456645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    }
457645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner  }
458f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
459245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar  if (RegNo == 0)
4600e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar    return Error(Tok.getLoc(), "invalid register name");
4610e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar
46229ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner  EndLoc = Tok.getLoc();
463b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat identifier token.
46416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  return false;
465092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar}
466092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar
467309264d1e4c41923ff04fb6786749185cf3b9de1Chris LattnerX86Operand *X86ATTAsmParser::ParseOperand() {
46816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  switch (getLexer().getKind()) {
46916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  default:
470eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    // Parse a memory operand with no segment register.
471eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    return ParseMemOperand(0, Parser.getTok().getLoc());
47223075746a1418f281bc2a088ea85560bfd833599Chris Lattner  case AsmToken::Percent: {
473eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    // Read the register.
47423075746a1418f281bc2a088ea85560bfd833599Chris Lattner    unsigned RegNo;
47529ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    SMLoc Start, End;
47629ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    if (ParseRegister(RegNo, Start, End)) return 0;
4773c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes    if (RegNo == X86::EIZ || RegNo == X86::RIZ) {
4783c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes      Error(Start, "eiz and riz can only be used as index registers");
4793c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes      return 0;
4803c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes    }
481f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
482eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    // If this is a segment register followed by a ':', then this is the start
483eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    // of a memory reference, otherwise this is a normal register reference.
484eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    if (getLexer().isNot(AsmToken::Colon))
485eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner      return X86Operand::CreateReg(RegNo, Start, End);
486f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
487f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
488eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    getParser().Lex(); // Eat the colon.
489eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    return ParseMemOperand(RegNo, Start);
49023075746a1418f281bc2a088ea85560bfd833599Chris Lattner  }
49116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  case AsmToken::Dollar: {
49216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // $42 -> immediate.
49318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    SMLoc Start = Parser.getTok().getLoc(), End;
494b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
4958c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar    const MCExpr *Val;
49654482b472a888c9efe003ad694ecf47b21878f0eChris Lattner    if (getParser().ParseExpression(Val, End))
497309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner      return 0;
498b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner    return X86Operand::CreateImm(Val, Start, End);
49916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
50016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
50116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar}
50216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
503eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner/// ParseMemOperand: segment: disp(basereg, indexreg, scale).  The '%ds:' prefix
504eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner/// has already been parsed if present.
505eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris LattnerX86Operand *X86ATTAsmParser::ParseMemOperand(unsigned SegReg, SMLoc MemStart) {
506f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
50716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  // We have to disambiguate a parenthesized expression "(4+5)" from the start
50816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)".  The
50975f265fbbbb64ab060bf41c5a4677ce56014ce9fChris Lattner  // only way to do this without lookahead is to eat the '(' and see what is
51075f265fbbbb64ab060bf41c5a4677ce56014ce9fChris Lattner  // after it.
5118c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar  const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext());
51216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  if (getLexer().isNot(AsmToken::LParen)) {
51354482b472a888c9efe003ad694ecf47b21878f0eChris Lattner    SMLoc ExprEnd;
51454482b472a888c9efe003ad694ecf47b21878f0eChris Lattner    if (getParser().ParseExpression(Disp, ExprEnd)) return 0;
515f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
51616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // After parsing the base expression we could either have a parenthesized
51716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // memory address or not.  If not, return now.  If so, eat the (.
51816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    if (getLexer().isNot(AsmToken::LParen)) {
519c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar      // Unless we have a segment register, treat this as an immediate.
520309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner      if (SegReg == 0)
521b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar        return X86Operand::CreateMem(Disp, MemStart, ExprEnd);
5220a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner      return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd);
52316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    }
524f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
52516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // Eat the '('.
526b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
52716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  } else {
52816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // Okay, we have a '('.  We don't know if this is an expression or not, but
52916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // so we have to eat the ( to see beyond it.
53018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    SMLoc LParenLoc = Parser.getTok().getLoc();
531b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat the '('.
532f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
5337b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby    if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) {
53416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // Nothing to do here, fall into the code below with the '(' part of the
53516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // memory operand consumed.
53616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    } else {
537b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner      SMLoc ExprEnd;
538f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
53916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // It must be an parenthesized expression, parse it now.
540b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner      if (getParser().ParseParenExpression(Disp, ExprEnd))
541309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        return 0;
542f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
54316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // After parsing the base expression we could either have a parenthesized
54416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // memory address or not.  If not, return now.  If so, eat the (.
54516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      if (getLexer().isNot(AsmToken::LParen)) {
546c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar        // Unless we have a segment register, treat this as an immediate.
547309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        if (SegReg == 0)
548b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar          return X86Operand::CreateMem(Disp, LParenLoc, ExprEnd);
5490a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner        return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd);
55016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      }
551f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
55216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // Eat the '('.
553b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();
55416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    }
55516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
556f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
55716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  // If we reached here, then we just ate the ( of the memory operand.  Process
55816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  // the rest of the memory operand.
559022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
560f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
56129ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner  if (getLexer().is(AsmToken::Percent)) {
56229ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    SMLoc L;
56329ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    if (ParseRegister(BaseReg, L, L)) return 0;
5643c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes    if (BaseReg == X86::EIZ || BaseReg == X86::RIZ) {
5653c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes      Error(L, "eiz and riz can only be used as index registers");
5663c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes      return 0;
5673c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes    }
56829ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner  }
569f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
57016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  if (getLexer().is(AsmToken::Comma)) {
571b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat the comma.
57216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
57316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // Following the comma we should have either an index register, or a scale
57416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // value. We don't support the later form, but we want to parse it
57516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // correctly.
57616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    //
57716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // Not that even though it would be completely consistent to support syntax
5783c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes    // like "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this.
5797b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby    if (getLexer().is(AsmToken::Percent)) {
58029ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner      SMLoc L;
58129ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner      if (ParseRegister(IndexReg, L, L)) return 0;
582f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
58316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      if (getLexer().isNot(AsmToken::RParen)) {
58416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar        // Parse the scale amount:
58516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar        //  ::= ',' [scale-expression]
586309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        if (getLexer().isNot(AsmToken::Comma)) {
58718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan          Error(Parser.getTok().getLoc(),
588309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner                "expected comma in scale expression");
589309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner          return 0;
590309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        }
591b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan        Parser.Lex(); // Eat the comma.
59216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
59316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar        if (getLexer().isNot(AsmToken::RParen)) {
59418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan          SMLoc Loc = Parser.getTok().getLoc();
59516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
59616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar          int64_t ScaleVal;
59716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar          if (getParser().ParseAbsoluteExpression(ScaleVal))
598309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner            return 0;
599f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
60016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar          // Validate the scale amount.
601309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner          if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8){
602309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner            Error(Loc, "scale factor in address must be 1, 2, 4 or 8");
603309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner            return 0;
604309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner          }
60516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar          Scale = (unsigned)ScaleVal;
60616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar        }
60716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      }
60816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    } else if (getLexer().isNot(AsmToken::RParen)) {
609ee9102587e7f6fc95de9fc5731b341eeb9bfc3caDaniel Dunbar      // A scale amount without an index is ignored.
61016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // index.
61118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan      SMLoc Loc = Parser.getTok().getLoc();
61216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
61316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      int64_t Value;
61416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      if (getParser().ParseAbsoluteExpression(Value))
615309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        return 0;
616f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
617ee9102587e7f6fc95de9fc5731b341eeb9bfc3caDaniel Dunbar      if (Value != 1)
618ee9102587e7f6fc95de9fc5731b341eeb9bfc3caDaniel Dunbar        Warning(Loc, "scale factor without index register is ignored");
619ee9102587e7f6fc95de9fc5731b341eeb9bfc3caDaniel Dunbar      Scale = 1;
62016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    }
62116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
622f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
62316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  // Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
624309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner  if (getLexer().isNot(AsmToken::RParen)) {
62518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    Error(Parser.getTok().getLoc(), "unexpected token in memory operand");
626309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner    return 0;
627309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner  }
62818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  SMLoc MemEnd = Parser.getTok().getLoc();
629b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat the ')'.
630f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
6310a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner  return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale,
6320a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner                               MemStart, MemEnd);
633dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar}
634dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar
6359898671a74d3fc924347e679c45edaa685b3fe6eChris Lattnerbool X86ATTAsmParser::
63638e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin KramerParseInstruction(StringRef Name, SMLoc NameLoc,
6379898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner                 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
638693173feefaa326fad0e386470846fb3199ba381Chris Lattner  StringRef PatchedName = Name;
63939e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar
640d8f717911dcdccb1a60b3049ea22c7767970dcb7Chris Lattner  // FIXME: Hack to recognize setneb as setne.
641d8f717911dcdccb1a60b3049ea22c7767970dcb7Chris Lattner  if (PatchedName.startswith("set") && PatchedName.endswith("b") &&
642d8f717911dcdccb1a60b3049ea22c7767970dcb7Chris Lattner      PatchedName != "setb" && PatchedName != "setnb")
643d8f717911dcdccb1a60b3049ea22c7767970dcb7Chris Lattner    PatchedName = PatchedName.substr(0, Name.size()-1);
644d8f717911dcdccb1a60b3049ea22c7767970dcb7Chris Lattner
64539e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar  // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}.
64639e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar  const MCExpr *ExtraImmOp = 0;
647428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes  if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) &&
64839e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      (PatchedName.endswith("ss") || PatchedName.endswith("sd") ||
64939e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar       PatchedName.endswith("ps") || PatchedName.endswith("pd"))) {
650428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes    bool IsVCMP = PatchedName.startswith("vcmp");
651428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes    unsigned SSECCIdx = IsVCMP ? 4 : 3;
65239e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar    unsigned SSEComparisonCode = StringSwitch<unsigned>(
653428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes      PatchedName.slice(SSECCIdx, PatchedName.size() - 2))
654cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("eq",          0)
655cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("lt",          1)
656cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("le",          2)
657cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("unord",       3)
658cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("neq",         4)
659cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("nlt",         5)
660cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("nle",         6)
661cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("ord",         7)
662cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("eq_uq",       8)
663cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("nge",         9)
664cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("ngt",      0x0A)
665cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("false",    0x0B)
666cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("neq_oq",   0x0C)
667cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("ge",       0x0D)
668cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("gt",       0x0E)
669cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("true",     0x0F)
670cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("eq_os",    0x10)
671cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("lt_oq",    0x11)
672cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("le_oq",    0x12)
673cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("unord_s",  0x13)
674cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("neq_us",   0x14)
675cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("nlt_uq",   0x15)
676cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("nle_uq",   0x16)
677cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("ord_s",    0x17)
678cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("eq_us",    0x18)
679cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("nge_uq",   0x19)
680cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("ngt_uq",   0x1A)
681cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("false_os", 0x1B)
682cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("neq_os",   0x1C)
683cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("ge_oq",    0x1D)
684cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("gt_oq",    0x1E)
685cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("true_us",  0x1F)
68639e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      .Default(~0U);
68739e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar    if (SSEComparisonCode != ~0U) {
68839e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      ExtraImmOp = MCConstantExpr::Create(SSEComparisonCode,
68939e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar                                          getParser().getContext());
69039e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      if (PatchedName.endswith("ss")) {
691428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes        PatchedName = IsVCMP ? "vcmpss" : "cmpss";
69239e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      } else if (PatchedName.endswith("sd")) {
693428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes        PatchedName = IsVCMP ? "vcmpsd" : "cmpsd";
69439e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      } else if (PatchedName.endswith("ps")) {
695428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes        PatchedName = IsVCMP ? "vcmpps" : "cmpps";
69639e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      } else {
69739e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar        assert(PatchedName.endswith("pd") && "Unexpected mnemonic!");
698428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes        PatchedName = IsVCMP ? "vcmppd" : "cmppd";
69939e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      }
70039e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar    }
70139e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar  }
702f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes
7031b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar  Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
70416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
70539e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar  if (ExtraImmOp)
70639e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar    Operands.push_back(X86Operand::CreateImm(ExtraImmOp, NameLoc, NameLoc));
707c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
708c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
7092544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  // Determine whether this is an instruction prefix.
7102544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  bool isPrefix =
711693173feefaa326fad0e386470846fb3199ba381Chris Lattner    Name == "lock" || Name == "rep" ||
712693173feefaa326fad0e386470846fb3199ba381Chris Lattner    Name == "repe" || Name == "repz" ||
713beb6898df8f96ccea4ae147587479b507bb3e491Rafael Espindola    Name == "repne" || Name == "repnz" ||
714bfd2d26159c87262fcf462ea442f99478a2093c9Rafael Espindola    Name == "rex64" || Name == "data16";
715c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
716c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
7172544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  // This does the actual operand parsing.  Don't parse any more if we have a
7182544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we
7192544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  // just want to parse the "lock" as the first instruction and the "incl" as
7202544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  // the next one.
7212544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  if (getLexer().isNot(AsmToken::EndOfStatement) && !isPrefix) {
7220db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar
7230db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar    // Parse '*' modifier.
7240db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar    if (getLexer().is(AsmToken::Star)) {
72518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan      SMLoc Loc = Parser.getTok().getLoc();
726b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner      Operands.push_back(X86Operand::CreateToken("*", Loc));
727b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex(); // Eat the star.
7280db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar    }
7290db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar
73016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // Read the first operand.
731309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner    if (X86Operand *Op = ParseOperand())
732309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner      Operands.push_back(Op);
733cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    else {
734cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      Parser.EatToEndOfStatement();
73516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      return true;
736cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    }
73739e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar
73816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    while (getLexer().is(AsmToken::Comma)) {
739b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();  // Eat the comma.
74016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
74116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // Parse and remember the operand.
742309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner      if (X86Operand *Op = ParseOperand())
743309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        Operands.push_back(Op);
744cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      else {
745cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        Parser.EatToEndOfStatement();
74616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar        return true;
747cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      }
74816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    }
749c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
750cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    if (getLexer().isNot(AsmToken::EndOfStatement)) {
751c146c4d47a7ec54c14e730c30bea821c34dc4c48Chris Lattner      SMLoc Loc = getLexer().getLoc();
752cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      Parser.EatToEndOfStatement();
753c146c4d47a7ec54c14e730c30bea821c34dc4c48Chris Lattner      return Error(Loc, "unexpected token in argument list");
754cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    }
75516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
756c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
7572544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  if (getLexer().is(AsmToken::EndOfStatement))
7582544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner    Parser.Lex(); // Consume the EndOfStatement
75976331754d4a06e2394c15ae8f4870f4aeaf5ca1fKevin Enderby  else if (isPrefix && getLexer().is(AsmToken::Slash))
76076331754d4a06e2394c15ae8f4870f4aeaf5ca1fKevin Enderby    Parser.Lex(); // Consume the prefix separator Slash
76116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
76298c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner  // This is a terrible hack to handle "out[bwl]? %al, (%dx)" ->
76398c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner  // "outb %al, %dx".  Out doesn't take a memory form, but this is a widely
76498c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner  // documented form in various unofficial manuals, so a lot of code uses it.
76598c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner  if ((Name == "outb" || Name == "outw" || Name == "outl" || Name == "out") &&
76698c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      Operands.size() == 3) {
76798c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner    X86Operand &Op = *(X86Operand*)Operands.back();
76898c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner    if (Op.isMem() && Op.Mem.SegReg == 0 &&
76998c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner        isa<MCConstantExpr>(Op.Mem.Disp) &&
77098c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner        cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
77198c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner        Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
77298c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      SMLoc Loc = Op.getEndLoc();
77398c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      Operands.back() = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
77498c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      delete &Op;
77598c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner    }
77698c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner  }
77700743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger  // Same hack for "in[bwl]? (%dx), %al" -> "inb %dx, %al".
77800743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger  if ((Name == "inb" || Name == "inw" || Name == "inl" || Name == "in") &&
77900743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger      Operands.size() == 3) {
78000743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger    X86Operand &Op = *(X86Operand*)Operands.begin()[1];
78100743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger    if (Op.isMem() && Op.Mem.SegReg == 0 &&
78200743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger        isa<MCConstantExpr>(Op.Mem.Disp) &&
78300743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger        cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
78400743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger        Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
78500743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger      SMLoc Loc = Op.getEndLoc();
78600743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger      Operands.begin()[1] = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
78700743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger      delete &Op;
78800743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger    }
78900743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger  }
79096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  // Transform "ins[bwl] %dx, %es:(%edi)" into "ins[bwl]"
79196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  if (Name.startswith("ins") && Operands.size() == 3 &&
79296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      (Name == "insb" || Name == "insw" || Name == "insl")) {
79396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand &Op = *(X86Operand*)Operands.begin()[1];
79496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand &Op2 = *(X86Operand*)Operands.begin()[2];
79596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    if (Op.isReg() && Op.getReg() == X86::DX && isDstOp(Op2)) {
79696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      Operands.pop_back();
79796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      Operands.pop_back();
79896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      delete &Op;
79996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      delete &Op2;
80096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    }
80196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  }
80296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger
80396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  // Transform "outs[bwl] %ds:(%esi), %dx" into "out[bwl]"
80496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  if (Name.startswith("outs") && Operands.size() == 3 &&
80596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      (Name == "outsb" || Name == "outsw" || Name == "outsl")) {
80696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand &Op = *(X86Operand*)Operands.begin()[1];
80796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand &Op2 = *(X86Operand*)Operands.begin()[2];
80896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    if (isSrcOp(Op) && Op2.isReg() && Op2.getReg() == X86::DX) {
80996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      Operands.pop_back();
81096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      Operands.pop_back();
81196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      delete &Op;
81296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      delete &Op2;
81396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    }
81496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  }
81596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger
81696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  // Transform "movs[bwl] %ds:(%esi), %es:(%edi)" into "movs[bwl]"
81796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  if (Name.startswith("movs") && Operands.size() == 3 &&
81896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      (Name == "movsb" || Name == "movsw" || Name == "movsl" ||
81959ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng       (is64BitMode() && Name == "movsq"))) {
82096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand &Op = *(X86Operand*)Operands.begin()[1];
82196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand &Op2 = *(X86Operand*)Operands.begin()[2];
82296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    if (isSrcOp(Op) && isDstOp(Op2)) {
82396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      Operands.pop_back();
82496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      Operands.pop_back();
82596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      delete &Op;
82696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      delete &Op2;
82796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    }
82896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  }
82996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  // Transform "lods[bwl] %ds:(%esi),{%al,%ax,%eax,%rax}" into "lods[bwl]"
83096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  if (Name.startswith("lods") && Operands.size() == 3 &&
83196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      (Name == "lods" || Name == "lodsb" || Name == "lodsw" ||
83259ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng       Name == "lodsl" || (is64BitMode() && Name == "lodsq"))) {
83396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]);
83496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand *Op2 = static_cast<X86Operand*>(Operands[2]);
83596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    if (isSrcOp(*Op1) && Op2->isReg()) {
83696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      const char *ins;
83796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      unsigned reg = Op2->getReg();
83896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      bool isLods = Name == "lods";
83996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      if (reg == X86::AL && (isLods || Name == "lodsb"))
84096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = "lodsb";
84196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      else if (reg == X86::AX && (isLods || Name == "lodsw"))
84296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = "lodsw";
84396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      else if (reg == X86::EAX && (isLods || Name == "lodsl"))
84496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = "lodsl";
84596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      else if (reg == X86::RAX && (isLods || Name == "lodsq"))
84696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = "lodsq";
84796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      else
84896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = NULL;
84996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      if (ins != NULL) {
85096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        Operands.pop_back();
85196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        Operands.pop_back();
85296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        delete Op1;
85396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        delete Op2;
85496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        if (Name != ins)
85596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger          static_cast<X86Operand*>(Operands[0])->setTokenValue(ins);
85696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      }
85796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    }
85896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  }
85996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  // Transform "stos[bwl] {%al,%ax,%eax,%rax},%es:(%edi)" into "stos[bwl]"
86096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  if (Name.startswith("stos") && Operands.size() == 3 &&
86196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      (Name == "stos" || Name == "stosb" || Name == "stosw" ||
86259ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng       Name == "stosl" || (is64BitMode() && Name == "stosq"))) {
86396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]);
86496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand *Op2 = static_cast<X86Operand*>(Operands[2]);
86596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    if (isDstOp(*Op2) && Op1->isReg()) {
86696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      const char *ins;
86796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      unsigned reg = Op1->getReg();
86896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      bool isStos = Name == "stos";
86996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      if (reg == X86::AL && (isStos || Name == "stosb"))
87096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = "stosb";
87196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      else if (reg == X86::AX && (isStos || Name == "stosw"))
87296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = "stosw";
87396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      else if (reg == X86::EAX && (isStos || Name == "stosl"))
87496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = "stosl";
87596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      else if (reg == X86::RAX && (isStos || Name == "stosq"))
87696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = "stosq";
87796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      else
87896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = NULL;
87996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      if (ins != NULL) {
88096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        Operands.pop_back();
88196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        Operands.pop_back();
88296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        delete Op1;
88396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        delete Op2;
88496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        if (Name != ins)
88596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger          static_cast<X86Operand*>(Operands[0])->setTokenValue(ins);
88696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      }
88796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    }
88896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  }
88996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger
890e9e16a36d9ff355dab60e4b95673bf7a0cd27e86Chris Lattner  // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>.  Canonicalize to
891ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner  // "shift <op>".
892d5e7705a05947e60806b795880f09757e835f590Daniel Dunbar  if ((Name.startswith("shr") || Name.startswith("sar") ||
8938c24b0c6996a8f03ff32766f0695dcf19577af59Chris Lattner       Name.startswith("shl") || Name.startswith("sal") ||
8948c24b0c6996a8f03ff32766f0695dcf19577af59Chris Lattner       Name.startswith("rcl") || Name.startswith("rcr") ||
8958c24b0c6996a8f03ff32766f0695dcf19577af59Chris Lattner       Name.startswith("rol") || Name.startswith("ror")) &&
89647ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner      Operands.size() == 3) {
89747ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner    X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]);
89847ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner    if (Op1->isImm() && isa<MCConstantExpr>(Op1->getImm()) &&
89947ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner        cast<MCConstantExpr>(Op1->getImm())->getValue() == 1) {
90047ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner      delete Operands[1];
90147ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner      Operands.erase(Operands.begin() + 1);
90247ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner    }
903f2de13f8d7bed958538bbd9dbeb9b15ea48456ccDaniel Dunbar  }
90415f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner
90515f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner  // Transforms "int $3" into "int3" as a size optimization.  We can't write an
90615f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner  // instalias with an immediate operand yet.
90715f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner  if (Name == "int" && Operands.size() == 2) {
90815f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner    X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]);
90915f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner    if (Op1->isImm() && isa<MCConstantExpr>(Op1->getImm()) &&
91015f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner        cast<MCConstantExpr>(Op1->getImm())->getValue() == 3) {
91115f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner      delete Operands[1];
91215f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner      Operands.erase(Operands.begin() + 1);
91315f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner      static_cast<X86Operand*>(Operands[0])->setTokenValue("int3");
91415f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner    }
91515f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner  }
916c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
9179898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner  return false;
918a3af370dc12f6d5100da5d614ab0a62da135569aDaniel Dunbar}
919a3af370dc12f6d5100da5d614ab0a62da135569aDaniel Dunbar
9202d592d10a57887ebe7c43a5e610f4278dd6c5d20Chris Lattnerbool X86ATTAsmParser::
9217036f8be4df8a1a830ca01afe9497b035a5647d6Chris LattnerMatchAndEmitInstruction(SMLoc IDLoc,
9227c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner                        SmallVectorImpl<MCParsedAsmOperand*> &Operands,
9237036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner                        MCStreamer &Out) {
924f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar  assert(!Operands.empty() && "Unexpect empty operand list!");
9257c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner  X86Operand *Op = static_cast<X86Operand*>(Operands[0]);
9267c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner  assert(Op->isToken() && "Leading operand should always be a mnemonic!");
9277c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner
9287c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner  // First, handle aliases that expand to multiple instructions.
9297c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner  // FIXME: This should be replaced with a real .td file alias mechanism.
93090fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner  // Also, MatchInstructionImpl should do actually *do* the EmitInstruction
93190fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner  // call.
9320966ec08610c02c8556105f2fff88a7e7247a549Andrew Trick  if (Op->getToken() == "fstsw" || Op->getToken() == "fstcw" ||
9338b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner      Op->getToken() == "fstsww" || Op->getToken() == "fstcww" ||
934905f2e06691672c236ae864faf0ad7220afc2844Chris Lattner      Op->getToken() == "finit" || Op->getToken() == "fsave" ||
9355a378076a44ef3f507b91aa8e7715fabaec42074Kevin Enderby      Op->getToken() == "fstenv" || Op->getToken() == "fclex") {
9367c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner    MCInst Inst;
9377c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner    Inst.setOpcode(X86::WAIT);
9387c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner    Out.EmitInstruction(Inst);
939f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar
9400bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner    const char *Repl =
9410bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner      StringSwitch<const char*>(Op->getToken())
9428b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner        .Case("finit",  "fninit")
9438b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner        .Case("fsave",  "fnsave")
9448b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner        .Case("fstcw",  "fnstcw")
9458b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner        .Case("fstcww",  "fnstcw")
946905f2e06691672c236ae864faf0ad7220afc2844Chris Lattner        .Case("fstenv", "fnstenv")
9478b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner        .Case("fstsw",  "fnstsw")
9488b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner        .Case("fstsww", "fnstsw")
9498b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner        .Case("fclex",  "fnclex")
9500bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner        .Default(0);
9510bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner    assert(Repl && "Unknown wait-prefixed instruction");
952b0f96facd6e6637cb71bbeaf2f4e006f0b6348e3Benjamin Kramer    delete Operands[0];
9530bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner    Operands[0] = X86Operand::CreateToken(Repl, IDLoc);
9547c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner  }
955c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
956a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  bool WasOriginallyInvalidOperand = false;
957ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner  unsigned OrigErrorInfo;
9587036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner  MCInst Inst;
959c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
960c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // First, try a direct match.
961ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner  switch (MatchInstructionImpl(Operands, Inst, OrigErrorInfo)) {
962ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  case Match_Success:
9637036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner    Out.EmitInstruction(Inst);
964c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar    return false;
965ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  case Match_MissingFeature:
966ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
967ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    return true;
968b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar  case Match_ConversionFail:
969b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar    return Error(IDLoc, "unable to convert operands to instruction");
970a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  case Match_InvalidOperand:
971a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner    WasOriginallyInvalidOperand = true;
972a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner    break;
973a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  case Match_MnemonicFail:
974ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    break;
975ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  }
976c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
977c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // FIXME: Ideally, we would only attempt suffix matches for things which are
978c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // valid prefixes, and we could just infer the right unambiguous
979c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // type. However, that requires substantially more matcher support than the
980c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // following hack.
981c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
982c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // Change the operand to point to a temporary token.
983c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  StringRef Base = Op->getToken();
984f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar  SmallString<16> Tmp;
985f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar  Tmp += Base;
986f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar  Tmp += ' ';
987f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar  Op->setTokenValue(Tmp.str());
988c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
989fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  // If this instruction starts with an 'f', then it is a floating point stack
990fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  // instruction.  These come in up to three forms for 32-bit, 64-bit, and
991fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  // 80-bit floating point, which use the suffixes s,l,t respectively.
992fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  //
993fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  // Otherwise, we assume that this may be an integer instruction, which comes
994fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  // in 8/16/32/64-bit forms using the b,w,l,q suffixes respectively.
995fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0";
996fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner
997c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // Check for the various suffix matches.
998fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  Tmp[Base.size()] = Suffixes[0];
999fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  unsigned ErrorInfoIgnore;
1000fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  MatchResultTy Match1, Match2, Match3, Match4;
1001fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner
1002fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  Match1 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore);
1003fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  Tmp[Base.size()] = Suffixes[1];
1004fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  Match2 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore);
1005fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  Tmp[Base.size()] = Suffixes[2];
1006fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  Match3 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore);
1007fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  Tmp[Base.size()] = Suffixes[3];
1008fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  Match4 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore);
1009c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
1010c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // Restore the old token.
1011c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  Op->setTokenValue(Base);
1012c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
1013c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // If exactly one matched, then we treat that as a successful match (and the
1014c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // instruction will already have been filled in correctly, since the failing
1015c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // matches won't have modified it).
1016ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  unsigned NumSuccessfulMatches =
1017fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner    (Match1 == Match_Success) + (Match2 == Match_Success) +
1018fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner    (Match3 == Match_Success) + (Match4 == Match_Success);
10197036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner  if (NumSuccessfulMatches == 1) {
10207036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner    Out.EmitInstruction(Inst);
1021c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar    return false;
10227036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner  }
1023c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
1024ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  // Otherwise, the match failed, try to produce a decent error message.
1025f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar
102609062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar  // If we had multiple suffix matches, then identify this as an ambiguous
102709062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar  // match.
1028ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  if (NumSuccessfulMatches > 1) {
102909062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    char MatchChars[4];
103009062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    unsigned NumMatches = 0;
1031fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner    if (Match1 == Match_Success) MatchChars[NumMatches++] = Suffixes[0];
1032fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner    if (Match2 == Match_Success) MatchChars[NumMatches++] = Suffixes[1];
1033fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner    if (Match3 == Match_Success) MatchChars[NumMatches++] = Suffixes[2];
1034fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner    if (Match4 == Match_Success) MatchChars[NumMatches++] = Suffixes[3];
103509062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar
103609062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    SmallString<126> Msg;
103709062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    raw_svector_ostream OS(Msg);
103809062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    OS << "ambiguous instructions require an explicit suffix (could be ";
103909062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    for (unsigned i = 0; i != NumMatches; ++i) {
104009062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar      if (i != 0)
104109062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar        OS << ", ";
104209062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar      if (i + 1 == NumMatches)
104309062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar        OS << "or ";
104409062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar      OS << "'" << Base << MatchChars[i] << "'";
104509062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    }
104609062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    OS << ")";
104709062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    Error(IDLoc, OS.str());
1048ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    return true;
104909062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar  }
1050c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
1051a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  // Okay, we know that none of the variants matched successfully.
1052c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
1053a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  // If all of the instructions reported an invalid mnemonic, then the original
1054a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  // mnemonic was invalid.
1055fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  if ((Match1 == Match_MnemonicFail) && (Match2 == Match_MnemonicFail) &&
1056fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner      (Match3 == Match_MnemonicFail) && (Match4 == Match_MnemonicFail)) {
1057ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner    if (!WasOriginallyInvalidOperand) {
1058c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer      Error(IDLoc, "invalid instruction mnemonic '" + Base + "'");
1059ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner      return true;
1060ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner    }
1061ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner
1062ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner    // Recover location info for the operand if we know which was the problem.
1063ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner    SMLoc ErrorLoc = IDLoc;
1064ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner    if (OrigErrorInfo != ~0U) {
1065f884012c93578912556de6ab89ecebab79b4ee31Chris Lattner      if (OrigErrorInfo >= Operands.size())
1066f884012c93578912556de6ab89ecebab79b4ee31Chris Lattner        return Error(IDLoc, "too few operands for instruction");
1067c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
1068ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner      ErrorLoc = ((X86Operand*)Operands[OrigErrorInfo])->getStartLoc();
1069ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner      if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
1070ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner    }
1071ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner
1072f884012c93578912556de6ab89ecebab79b4ee31Chris Lattner    return Error(ErrorLoc, "invalid operand for instruction");
1073a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  }
1074c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
1075ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  // If one instruction matched with a missing feature, report this as a
1076ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  // missing feature.
1077fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  if ((Match1 == Match_MissingFeature) + (Match2 == Match_MissingFeature) +
1078fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner      (Match3 == Match_MissingFeature) + (Match4 == Match_MissingFeature) == 1){
1079ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1080ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    return true;
1081ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  }
1082c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
1083a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  // If one instruction matched with an invalid operand, report this as an
1084a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  // operand failure.
1085fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  if ((Match1 == Match_InvalidOperand) + (Match2 == Match_InvalidOperand) +
1086fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner      (Match3 == Match_InvalidOperand) + (Match4 == Match_InvalidOperand) == 1){
1087a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner    Error(IDLoc, "invalid operand for instruction");
1088a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner    return true;
1089a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  }
1090c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
1091ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  // If all of these were an outright failure, report it in a useless way.
1092ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  // FIXME: We should give nicer diagnostics about the exact failure.
1093a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  Error(IDLoc, "unknown use of instruction mnemonic without a size suffix");
1094c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  return true;
1095c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar}
1096c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
1097c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
1098537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattnerbool X86ATTAsmParser::ParseDirective(AsmToken DirectiveID) {
1099537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner  StringRef IDVal = DirectiveID.getIdentifier();
1100537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner  if (IDVal == ".word")
1101537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner    return ParseDirectiveWord(2, DirectiveID.getLoc());
1102537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner  return true;
1103537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner}
1104537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner
1105537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner/// ParseDirectiveWord
1106537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner///  ::= .word [ expression (, expression)* ]
1107537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattnerbool X86ATTAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
1108537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1109537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner    for (;;) {
1110537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner      const MCExpr *Value;
1111537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner      if (getParser().ParseExpression(Value))
1112537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner        return true;
1113537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner
1114537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner      getParser().getStreamer().EmitValue(Value, Size, 0 /*addrspace*/);
1115537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner
1116537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner      if (getLexer().is(AsmToken::EndOfStatement))
1117537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner        break;
1118537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner
1119537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner      // FIXME: Improve diagnostic.
1120537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner      if (getLexer().isNot(AsmToken::Comma))
1121537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner        return Error(L, "unexpected token in directive");
1122537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner      Parser.Lex();
1123537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner    }
1124537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner  }
1125537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner
1126537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner  Parser.Lex();
1127537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner  return false;
1128537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner}
1129537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner
1130537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner
1131537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner
1132537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner
1133e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callananextern "C" void LLVMInitializeX86AsmLexer();
1134e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan
1135092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar// Force static initialization.
1136092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbarextern "C" void LLVMInitializeX86AsmParser() {
1137ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  RegisterAsmParser<X86ATTAsmParser> X(TheX86_32Target);
1138ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  RegisterAsmParser<X86ATTAsmParser> Y(TheX86_64Target);
1139e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan  LLVMInitializeX86AsmLexer();
1140092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar}
11410e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar
11420692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER
11430692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION
11440e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar#include "X86GenAsmMatcher.inc"
1145