X86AsmParser.cpp revision dd929fc704054fa79cc1171354f95d91a5b62de2
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
1094b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "MCTargetDesc/X86BaseInfo.h"
1194b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/MC/MCTargetAsmParser.h"
129c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby#include "llvm/MC/MCStreamer.h"
138c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar#include "llvm/MC/MCExpr.h"
14a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar#include "llvm/MC/MCInst.h"
155de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng#include "llvm/MC/MCRegisterInfo.h"
16ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng#include "llvm/MC/MCSubtargetInfo.h"
17c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmLexer.h"
18c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmParser.h"
19c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
2075ca4b94bd9dcd3952fdc237429342a2154ba142Benjamin Kramer#include "llvm/ADT/OwningPtr.h"
2133d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner#include "llvm/ADT/SmallString.h"
2233d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner#include "llvm/ADT/SmallVector.h"
2333d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner#include "llvm/ADT/StringSwitch.h"
2433d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner#include "llvm/ADT/Twine.h"
2516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar#include "llvm/Support/SourceMgr.h"
263e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h"
2709062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar#include "llvm/Support/raw_ostream.h"
28ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
29092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbarusing namespace llvm;
30092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar
31092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbarnamespace {
32c6b79ac88e52367dd2afdf03b1be81b10345c0bbBenjamin Kramerstruct X86Operand;
33092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar
34dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patelclass X86AsmParser : public MCTargetAsmParser {
35ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  MCSubtargetInfo &STI;
3616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  MCAsmParser &Parser;
37c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
3816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbarprivate:
3916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  MCAsmParser &getParser() const { return Parser; }
40a2edbabcb86f213eca6daeda5d801f8c7b1e44b2Daniel Dunbar
4116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
4216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
43d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner  bool Error(SMLoc L, const Twine &Msg,
44d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner             ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()) {
45d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner    return Parser.Error(L, Msg, Ranges);
46d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner  }
4716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
48309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner  X86Operand *ParseOperand();
490a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  X86Operand *ParseATTOperand();
500a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  X86Operand *ParseIntelOperand();
51eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner  X86Operand *ParseMemOperand(unsigned SegReg, SMLoc StartLoc);
529c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby
539c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby  bool ParseDirectiveWord(unsigned Size, SMLoc L);
54bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng  bool ParseDirectiveCode(StringRef IDVal, SMLoc L);
559c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby
567036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner  bool MatchAndEmitInstruction(SMLoc IDLoc,
577c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner                               SmallVectorImpl<MCParsedAsmOperand*> &Operands,
587036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner                               MCStreamer &Out);
5920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
6096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  /// isSrcOp - Returns true if operand is either (%rsi) or %ds:%(rsi)
6196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  /// in 64bit mode or (%edi) or %es:(%edi) in 32bit mode.
6296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  bool isSrcOp(X86Operand &Op);
6396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger
6496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  /// isDstOp - Returns true if operand is either %es:(%rdi) in 64bit mode
6596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  /// or %es:(%edi) in 32bit mode.
6696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  bool isDstOp(X86Operand &Op);
6796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger
6859ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  bool is64BitMode() const {
69ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    // FIXME: Can tablegen auto-generate this?
70ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    return (STI.getFeatureBits() & X86::Mode64Bit) != 0;
71ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
72bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng  void SwitchMode() {
73bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(X86::Mode64Bit));
74bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    setAvailableFeatures(FB);
75bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng  }
76ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
7754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  /// @name Auto-generated Matcher Functions
7854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  /// {
79c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
800692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER
810692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "X86GenAsmMatcher.inc"
82c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
830e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar  /// }
8416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
8516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbarpublic:
86dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patel  X86AsmParser(MCSubtargetInfo &sti, MCAsmParser &parser)
8794b9550a32d189704a8eae55505edf62662c0534Evan Cheng    : MCTargetAsmParser(), STI(sti), Parser(parser) {
88c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
8954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar    // Initialize the set of available features.
90ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
9154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  }
92bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky  virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
9316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
9438e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc,
959898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner                                SmallVectorImpl<MCParsedAsmOperand*> &Operands);
969c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby
979c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby  virtual bool ParseDirective(AsmToken DirectiveID);
9816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar};
9937dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner} // end anonymous namespace
10037dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner
101e9b466d4f09de3b46c0d0d1e71cabddc7cc9021bSean Callanan/// @name Auto-generated Match Functions
102f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes/// {
103e9b466d4f09de3b46c0d0d1e71cabddc7cc9021bSean Callanan
104b8d6e98e566724f58344d275a4bd675249bb713aChris Lattnerstatic unsigned MatchRegisterName(StringRef Name);
105e9b466d4f09de3b46c0d0d1e71cabddc7cc9021bSean Callanan
106e9b466d4f09de3b46c0d0d1e71cabddc7cc9021bSean Callanan/// }
10737dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner
10837dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattnernamespace {
10916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
11016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar/// X86Operand - Instances of this class represent a parsed X86 machine
11116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar/// instruction.
11245220a84394758c86cc29ee0e3fe6738946fbcd0Chris Lattnerstruct X86Operand : public MCParsedAsmOperand {
1131f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner  enum KindTy {
11420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    Token,
11516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    Register,
11616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    Immediate,
11716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    Memory
11816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  } Kind;
11916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
12029ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner  SMLoc StartLoc, EndLoc;
121f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
12216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  union {
12316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    struct {
12420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar      const char *Data;
12520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar      unsigned Length;
12620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    } Tok;
12720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
12820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    struct {
12916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      unsigned RegNo;
13016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    } Reg;
13116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
13216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    struct {
1338c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar      const MCExpr *Val;
13416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    } Imm;
13516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
13616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    struct {
13716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      unsigned SegReg;
1388c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar      const MCExpr *Disp;
13916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      unsigned BaseReg;
14016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      unsigned IndexReg;
14116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      unsigned Scale;
142c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel      unsigned Size;
14316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    } Mem;
144dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar  };
14516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
1460a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner  X86Operand(KindTy K, SMLoc Start, SMLoc End)
1471f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner    : Kind(K), StartLoc(Start), EndLoc(End) {}
148c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
1491f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner  /// getStartLoc - Get the location of the first token of this operand.
1501f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner  SMLoc getStartLoc() const { return StartLoc; }
1511f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner  /// getEndLoc - Get the location of the last token of this operand.
1521f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner  SMLoc getEndLoc() const { return EndLoc; }
153d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner
154d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner  SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
1551f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner
156b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbach  virtual void print(raw_ostream &OS) const {}
157b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar
15820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  StringRef getToken() const {
15920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    assert(Kind == Token && "Invalid access!");
16020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    return StringRef(Tok.Data, Tok.Length);
16120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  }
162c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  void setTokenValue(StringRef Value) {
163c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar    assert(Kind == Token && "Invalid access!");
164c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar    Tok.Data = Value.data();
165c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar    Tok.Length = Value.size();
166c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  }
16720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
16816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  unsigned getReg() const {
16916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    assert(Kind == Register && "Invalid access!");
17016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    return Reg.RegNo;
17116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
17216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
1738c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar  const MCExpr *getImm() const {
174022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Immediate && "Invalid access!");
175022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Imm.Val;
176022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
177022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar
1788c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar  const MCExpr *getMemDisp() const {
179022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Memory && "Invalid access!");
180022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Mem.Disp;
181022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
182022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  unsigned getMemSegReg() const {
183022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Memory && "Invalid access!");
184022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Mem.SegReg;
185022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
186022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  unsigned getMemBaseReg() const {
187022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Memory && "Invalid access!");
188022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Mem.BaseReg;
189022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
190022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  unsigned getMemIndexReg() const {
191022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Memory && "Invalid access!");
192022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Mem.IndexReg;
193022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
194022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  unsigned getMemScale() const {
195022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Memory && "Invalid access!");
196022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Mem.Scale;
197022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
198022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar
199a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  bool isToken() const {return Kind == Token; }
20020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
20120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  bool isImm() const { return Kind == Immediate; }
202f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
20362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar  bool isImmSExti16i8() const {
2045fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar    if (!isImm())
2055fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar      return false;
2065fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar
20762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // If this isn't a constant expr, just assume it fits and let relaxation
20862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // handle it.
20962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
21062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    if (!CE)
21162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar      return true;
21262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar
21362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // Otherwise, check the value is in a range that makes sense for this
21462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // extension.
21562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    uint64_t Value = CE->getValue();
21662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    return ((                                  Value <= 0x000000000000007FULL)||
21762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar            (0x000000000000FF80ULL <= Value && Value <= 0x000000000000FFFFULL)||
21862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar            (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
21962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar  }
22062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar  bool isImmSExti32i8() const {
22162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    if (!isImm())
22262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar      return false;
2235fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar
22462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // If this isn't a constant expr, just assume it fits and let relaxation
22562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // handle it.
22662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
22762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    if (!CE)
22862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar      return true;
22962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar
23062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // Otherwise, check the value is in a range that makes sense for this
23162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // extension.
23262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    uint64_t Value = CE->getValue();
23362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    return ((                                  Value <= 0x000000000000007FULL)||
23462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar            (0x00000000FFFFFF80ULL <= Value && Value <= 0x00000000FFFFFFFFULL)||
23562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar            (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
2365fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar  }
237c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby  bool isImmZExtu32u8() const {
238c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby    if (!isImm())
239c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby      return false;
240c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby
241c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby    // If this isn't a constant expr, just assume it fits and let relaxation
242c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby    // handle it.
243c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
244c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby    if (!CE)
245c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby      return true;
246c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby
247c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby    // Otherwise, check the value is in a range that makes sense for this
248c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby    // extension.
249c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby    uint64_t Value = CE->getValue();
250c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby    return (Value <= 0x00000000000000FFULL);
251c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby  }
25262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar  bool isImmSExti64i8() const {
2531fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar    if (!isImm())
2541fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar      return false;
2551fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar
25662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // If this isn't a constant expr, just assume it fits and let relaxation
25762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // handle it.
25862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
25962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    if (!CE)
26062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar      return true;
26162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar
26262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // Otherwise, check the value is in a range that makes sense for this
26362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // extension.
26462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    uint64_t Value = CE->getValue();
26562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    return ((                                  Value <= 0x000000000000007FULL)||
26662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar            (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
26762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar  }
26862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar  bool isImmSExti64i32() const {
26962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    if (!isImm())
27062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar      return false;
2711fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar
27262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // If this isn't a constant expr, just assume it fits and let relaxation
27362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // handle it.
27462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
27562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    if (!CE)
27662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar      return true;
27762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar
27862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // Otherwise, check the value is in a range that makes sense for this
27962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // extension.
28062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    uint64_t Value = CE->getValue();
28162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    return ((                                  Value <= 0x000000007FFFFFFFULL)||
28262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar            (0xFFFFFFFF80000000ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
2831fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar  }
2841fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar
28520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  bool isMem() const { return Kind == Memory; }
286c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  bool isMem8() const {
287c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel    return Kind == Memory && (!Mem.Size || Mem.Size == 8);
288c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
289c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  bool isMem16() const {
290c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel    return Kind == Memory && (!Mem.Size || Mem.Size == 16);
291c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
292c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  bool isMem32() const {
293c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel    return Kind == Memory && (!Mem.Size || Mem.Size == 32);
294c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
295c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  bool isMem64() const {
296c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel    return Kind == Memory && (!Mem.Size || Mem.Size == 64);
297c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
298c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  bool isMem80() const {
299c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel    return Kind == Memory && (!Mem.Size || Mem.Size == 80);
300c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
301c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  bool isMem128() const {
302c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel    return Kind == Memory && (!Mem.Size || Mem.Size == 128);
303c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
304c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  bool isMem256() const {
305c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel    return Kind == Memory && (!Mem.Size || Mem.Size == 256);
306c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
30720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
308b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  bool isAbsMem() const {
309b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
3107b9147afa7d1875353e1c1347b6b6cf71f548229Daniel Dunbar      !getMemIndexReg() && getMemScale() == 1;
311b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  }
312b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar
31320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  bool isReg() const { return Kind == Register; }
31420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
3159c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
3169c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar    // Add as immediates when possible.
3179c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
3189c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
3199c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar    else
3209c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar      Inst.addOperand(MCOperand::CreateExpr(Expr));
3219c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar  }
3229c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar
3235c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar  void addRegOperands(MCInst &Inst, unsigned N) const {
32420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    assert(N == 1 && "Invalid number of operands!");
32520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getReg()));
32620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  }
32720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
3285c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar  void addImmOperands(MCInst &Inst, unsigned N) const {
32920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    assert(N == 1 && "Invalid number of operands!");
3309c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar    addExpr(Inst, getImm());
33120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  }
33220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
333c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  void addMem8Operands(MCInst &Inst, unsigned N) const {
334c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel    addMemOperands(Inst, N);
335c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
336c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  void addMem16Operands(MCInst &Inst, unsigned N) const {
337c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel    addMemOperands(Inst, N);
338c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
339c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  void addMem32Operands(MCInst &Inst, unsigned N) const {
340c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel    addMemOperands(Inst, N);
341c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
342c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  void addMem64Operands(MCInst &Inst, unsigned N) const {
343c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel    addMemOperands(Inst, N);
344c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
345c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  void addMem80Operands(MCInst &Inst, unsigned N) const {
346c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel    addMemOperands(Inst, N);
347c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
348c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  void addMem128Operands(MCInst &Inst, unsigned N) const {
349c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel    addMemOperands(Inst, N);
350c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
351c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  void addMem256Operands(MCInst &Inst, unsigned N) const {
352c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel    addMemOperands(Inst, N);
353c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
354c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel
3555c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar  void addMemOperands(MCInst &Inst, unsigned N) const {
356ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar    assert((N == 5) && "Invalid number of operands!");
35720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
35820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    Inst.addOperand(MCOperand::CreateImm(getMemScale()));
35920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemIndexReg()));
3609c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar    addExpr(Inst, getMemDisp());
361ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
362ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar  }
363ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar
364b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  void addAbsMemOperands(MCInst &Inst, unsigned N) const {
365b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    assert((N == 1) && "Invalid number of operands!");
366b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    Inst.addOperand(MCOperand::CreateExpr(getMemDisp()));
367b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  }
368b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar
369b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner  static X86Operand *CreateToken(StringRef Str, SMLoc Loc) {
370f82edaffb1a6d41bc89d86c69f53962e63621aadBenjamin Kramer    SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size() - 1);
371f82edaffb1a6d41bc89d86c69f53962e63621aadBenjamin Kramer    X86Operand *Res = new X86Operand(Token, Loc, EndLoc);
37229ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Tok.Data = Str.data();
37329ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Tok.Length = Str.size();
37420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    return Res;
37520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  }
37620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
37729ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner  static X86Operand *CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc) {
3781f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner    X86Operand *Res = new X86Operand(Register, StartLoc, EndLoc);
37929ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Reg.RegNo = RegNo;
38029ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    return Res;
38116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
38220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
383b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner  static X86Operand *CreateImm(const MCExpr *Val, SMLoc StartLoc, SMLoc EndLoc){
384b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner    X86Operand *Res = new X86Operand(Immediate, StartLoc, EndLoc);
38529ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Imm.Val = Val;
38629ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    return Res;
38716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
38820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
389b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  /// Create an absolute memory operand.
390b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  static X86Operand *CreateMem(const MCExpr *Disp, SMLoc StartLoc,
391c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel                               SMLoc EndLoc, unsigned Size = 0) {
392b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc);
393b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    Res->Mem.SegReg   = 0;
394b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    Res->Mem.Disp     = Disp;
395b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    Res->Mem.BaseReg  = 0;
396b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    Res->Mem.IndexReg = 0;
3977b9147afa7d1875353e1c1347b6b6cf71f548229Daniel Dunbar    Res->Mem.Scale    = 1;
398c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel    Res->Mem.Size     = Size;
399b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    return Res;
400b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  }
401b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar
402b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  /// Create a generalized memory operand.
403309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner  static X86Operand *CreateMem(unsigned SegReg, const MCExpr *Disp,
404309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner                               unsigned BaseReg, unsigned IndexReg,
405c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel                               unsigned Scale, SMLoc StartLoc, SMLoc EndLoc,
406c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel                               unsigned Size = 0) {
407b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    // We should never just have a displacement, that should be parsed as an
408b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    // absolute memory operand.
409c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar    assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
410c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar
411022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    // The scale should always be one of {1,2,4,8}.
412022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
41316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar           "Invalid scale!");
4140a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner    X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc);
41529ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Mem.SegReg   = SegReg;
41629ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Mem.Disp     = Disp;
41729ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Mem.BaseReg  = BaseReg;
41829ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Mem.IndexReg = IndexReg;
41929ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Mem.Scale    = Scale;
420c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel    Res->Mem.Size     = Size;
42129ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    return Res;
42216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
42316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar};
42416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
42537dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner} // end anonymous namespace.
42616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
427dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patelbool X86AsmParser::isSrcOp(X86Operand &Op) {
42859ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  unsigned basereg = is64BitMode() ? X86::RSI : X86::ESI;
42996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger
43096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  return (Op.isMem() &&
43196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    (Op.Mem.SegReg == 0 || Op.Mem.SegReg == X86::DS) &&
43296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    isa<MCConstantExpr>(Op.Mem.Disp) &&
43396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
43496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    Op.Mem.BaseReg == basereg && Op.Mem.IndexReg == 0);
43596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger}
43696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger
437dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patelbool X86AsmParser::isDstOp(X86Operand &Op) {
43859ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  unsigned basereg = is64BitMode() ? X86::RDI : X86::EDI;
43996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger
44096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  return Op.isMem() && Op.Mem.SegReg == X86::ES &&
44196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    isa<MCConstantExpr>(Op.Mem.Disp) &&
44296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
44396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    Op.Mem.BaseReg == basereg && Op.Mem.IndexReg == 0;
44496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger}
44516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
446dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patelbool X86AsmParser::ParseRegister(unsigned &RegNo,
447dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patel                                 SMLoc &StartLoc, SMLoc &EndLoc) {
44823075746a1418f281bc2a088ea85560bfd833599Chris Lattner  RegNo = 0;
44918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &TokPercent = Parser.getTok();
4507b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby  assert(TokPercent.is(AsmToken::Percent) && "Invalid token kind!");
45129ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner  StartLoc = TokPercent.getLoc();
452b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat percent token.
4537b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby
45418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
4550d6cd00dbe58b456d0d33663e6a36c270aad2b5aKevin Enderby  if (Tok.isNot(AsmToken::Identifier))
4565efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer    return Error(StartLoc, "invalid register name",
4575efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer                 SMRange(StartLoc, Tok.getEndLoc()));
45816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
4597b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby  RegNo = MatchRegisterName(Tok.getString());
460f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
46133d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner  // If the match failed, try the register name as lowercase.
46233d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner  if (RegNo == 0)
463590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer    RegNo = MatchRegisterName(Tok.getString().lower());
464c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
4655de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng  if (!is64BitMode()) {
4665de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng    // FIXME: This should be done using Requires<In32BitMode> and
4675de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng    // Requires<In64BitMode> so "eiz" usage in 64-bit instructions can be also
4685de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng    // checked.
4695de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng    // FIXME: Check AH, CH, DH, BH cannot be used in an instruction requiring a
4705de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng    // REX prefix.
4715de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng    if (RegNo == X86::RIZ ||
4725de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng        X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo) ||
4735de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng        X86II::isX86_64NonExtLowByteReg(RegNo) ||
4745de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng        X86II::isX86_64ExtendedReg(RegNo))
4755efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer      return Error(StartLoc, "register %"
4765efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer                   + Tok.getString() + " is only available in 64-bit mode",
4775efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer                   SMRange(StartLoc, Tok.getEndLoc()));
4785de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng  }
4793c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes
48033d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner  // Parse "%st" as "%st(0)" and "%st(1)", which is multiple tokens.
48133d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner  if (RegNo == 0 && (Tok.getString() == "st" || Tok.getString() == "ST")) {
482e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    RegNo = X86::ST0;
483e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    EndLoc = Tok.getLoc();
484e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    Parser.Lex(); // Eat 'st'
485f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
486e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    // Check to see if we have '(4)' after %st.
487e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    if (getLexer().isNot(AsmToken::LParen))
488e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner      return false;
489e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    // Lex the paren.
490e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    getParser().Lex();
491e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner
492e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    const AsmToken &IntTok = Parser.getTok();
493e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    if (IntTok.isNot(AsmToken::Integer))
494e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner      return Error(IntTok.getLoc(), "expected stack index");
495e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    switch (IntTok.getIntVal()) {
496e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 0: RegNo = X86::ST0; break;
497e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 1: RegNo = X86::ST1; break;
498e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 2: RegNo = X86::ST2; break;
499e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 3: RegNo = X86::ST3; break;
500e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 4: RegNo = X86::ST4; break;
501e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 5: RegNo = X86::ST5; break;
502e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 6: RegNo = X86::ST6; break;
503e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 7: RegNo = X86::ST7; break;
504e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    default: return Error(IntTok.getLoc(), "invalid stack index");
505e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    }
506f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
507e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    if (getParser().Lex().isNot(AsmToken::RParen))
508e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner      return Error(Parser.getTok().getLoc(), "expected ')'");
509f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
510e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    EndLoc = Tok.getLoc();
511e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    Parser.Lex(); // Eat ')'
512e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    return false;
513e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner  }
514f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
515645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner  // If this is "db[0-7]", match it as an alias
516645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner  // for dr[0-7].
517645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner  if (RegNo == 0 && Tok.getString().size() == 3 &&
518645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner      Tok.getString().startswith("db")) {
519645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    switch (Tok.getString()[2]) {
520645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '0': RegNo = X86::DR0; break;
521645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '1': RegNo = X86::DR1; break;
522645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '2': RegNo = X86::DR2; break;
523645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '3': RegNo = X86::DR3; break;
524645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '4': RegNo = X86::DR4; break;
525645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '5': RegNo = X86::DR5; break;
526645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '6': RegNo = X86::DR6; break;
527645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '7': RegNo = X86::DR7; break;
528645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    }
529f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
530645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    if (RegNo != 0) {
531645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner      EndLoc = Tok.getLoc();
532645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner      Parser.Lex(); // Eat it.
533645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner      return false;
534645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    }
535645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner  }
536f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
537245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar  if (RegNo == 0)
5385efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer    return Error(StartLoc, "invalid register name",
5395efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer                 SMRange(StartLoc, Tok.getEndLoc()));
5400e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar
5415efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer  EndLoc = Tok.getEndLoc();
542b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat identifier token.
54316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  return false;
544092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar}
545092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar
546dd929fc704054fa79cc1171354f95d91a5b62de2Devang PatelX86Operand *X86AsmParser::ParseOperand() {
5470a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  if (getParser().getAssemblerDialect())
5480a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel    return ParseIntelOperand();
5490a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  return ParseATTOperand();
5500a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel}
5510a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel
5520a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel/// getIntelRegister - If this is an intel register operand
5530a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel/// then return register number, otherwise return 0;
5540a338868b746f29d6d72fd95e425ec8696ed8024Devang Patelstatic unsigned getIntelRegisterOperand(StringRef Str) {
5550a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  unsigned RegNo = MatchRegisterName(Str);
5560a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  // If the match failed, try the register name as lowercase.
5570a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  if (RegNo == 0)
5580a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel    RegNo = MatchRegisterName(Str.lower());
5590a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  return RegNo;
5600a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel}
5610a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel
5620a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel/// isIntelMemOperand - If this is an intel memory operand
5630a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel/// then return true.
5640a338868b746f29d6d72fd95e425ec8696ed8024Devang Patelstatic bool isIntelMemOperand(StringRef OpStr, unsigned &Size) {
5650a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  Size = 0;
5660a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  if (OpStr == "BYTE") Size = 8;
5670a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  if (OpStr == "WORD") Size = 16;
5680a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  if (OpStr == "DWORD") Size = 32;
5690a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  if (OpStr == "QWORD") Size = 64;
5700a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  if (OpStr == "XWORD") Size = 80;
5710a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  if (OpStr == "XMMWORD") Size = 128;
5720a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  if (OpStr == "YMMWORD") Size = 256;
5730a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  return Size != 0;
5740a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel}
5750a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel
576dd929fc704054fa79cc1171354f95d91a5b62de2Devang PatelX86Operand *X86AsmParser::ParseIntelOperand() {
5770a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel
5780a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  const AsmToken &Tok = Parser.getTok();
5790a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  SMLoc Start = Parser.getTok().getLoc(), End;
5800a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel
5810a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  // register
5820a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  if(unsigned RegNo = getIntelRegisterOperand(Tok.getString())) {
5830a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel    Parser.Lex();
5840a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel    End = Parser.getTok().getLoc();
5850a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel    return X86Operand::CreateReg(RegNo, Start, End);
5860a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  }
5870a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel
5880a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  // mem operand
5890a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  unsigned SegReg = 0, BaseReg = 0, IndexReg = 0, Scale = 1;
5900a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  StringRef OpStr = Tok.getString();
5910a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  unsigned Size = 0;
5920a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  if (isIntelMemOperand(OpStr, Size)) {
5930a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel    Parser.Lex();
5940a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel    if (Tok.getString() == "PTR")
5950a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel      Parser.Lex();
5960a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel    else {
5970a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel      Error(Start, "unexpected token!");
5980a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel      return 0;
5990a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel    }
6000a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel
6010a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel    if (Tok.getString() == "[")
6020a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel      Parser.Lex();
6030a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel    else {
6040a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel      Error(Start, "unexpected token!");
6050a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel      return 0;
6060a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel    }
6070a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel
6080a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel    SMLoc LParenLoc = Parser.getTok().getLoc();
6090a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel    BaseReg = getIntelRegisterOperand(Tok.getString());
6100a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel    if (BaseReg == 0) {
6110a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel      Error(LParenLoc, "unexpected token!");
6120a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel      return 0;
6130a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel    }
6140a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel    Parser.Lex();
6150a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel    const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext());
6160a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel    SMLoc ExprEnd;
6170a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel    if (getParser().ParseExpression(Disp, ExprEnd)) return 0;
6180a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel    End = Parser.getTok().getLoc();
6190a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel    if (Tok.getString() == "]")
6200a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel      Parser.Lex();
6210a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel    if (BaseReg == 0) {
6220a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel      Error(End, "unexpected token!");
6230a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel      return 0;
6240a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel    }
6250a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel    return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale,
626c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel                                 Start, End, Size);
6270a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  }
6280a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel
6290a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  // immediate.
6300a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  const MCExpr *Val;
6310a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  if (!getParser().ParseExpression(Val, End)) {
6320a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel    End = Parser.getTok().getLoc();
6330a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel    return X86Operand::CreateImm(Val, Start, End);
6340a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  }
6350a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel
6360a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  return 0;
6370a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel}
6380a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel
639dd929fc704054fa79cc1171354f95d91a5b62de2Devang PatelX86Operand *X86AsmParser::ParseATTOperand() {
64016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  switch (getLexer().getKind()) {
64116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  default:
642eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    // Parse a memory operand with no segment register.
643eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    return ParseMemOperand(0, Parser.getTok().getLoc());
64423075746a1418f281bc2a088ea85560bfd833599Chris Lattner  case AsmToken::Percent: {
645eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    // Read the register.
64623075746a1418f281bc2a088ea85560bfd833599Chris Lattner    unsigned RegNo;
64729ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    SMLoc Start, End;
64829ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    if (ParseRegister(RegNo, Start, End)) return 0;
6493c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes    if (RegNo == X86::EIZ || RegNo == X86::RIZ) {
6505efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer      Error(Start, "%eiz and %riz can only be used as index registers",
6515efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer            SMRange(Start, End));
6523c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes      return 0;
6533c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes    }
654f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
655eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    // If this is a segment register followed by a ':', then this is the start
656eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    // of a memory reference, otherwise this is a normal register reference.
657eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    if (getLexer().isNot(AsmToken::Colon))
658eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner      return X86Operand::CreateReg(RegNo, Start, End);
659f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
660f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
661eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    getParser().Lex(); // Eat the colon.
662eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    return ParseMemOperand(RegNo, Start);
66323075746a1418f281bc2a088ea85560bfd833599Chris Lattner  }
66416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  case AsmToken::Dollar: {
66516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // $42 -> immediate.
66618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    SMLoc Start = Parser.getTok().getLoc(), End;
667b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
6688c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar    const MCExpr *Val;
66954482b472a888c9efe003ad694ecf47b21878f0eChris Lattner    if (getParser().ParseExpression(Val, End))
670309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner      return 0;
671b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner    return X86Operand::CreateImm(Val, Start, End);
67216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
67316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
67416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar}
67516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
676eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner/// ParseMemOperand: segment: disp(basereg, indexreg, scale).  The '%ds:' prefix
677eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner/// has already been parsed if present.
678dd929fc704054fa79cc1171354f95d91a5b62de2Devang PatelX86Operand *X86AsmParser::ParseMemOperand(unsigned SegReg, SMLoc MemStart) {
679f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
68016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  // We have to disambiguate a parenthesized expression "(4+5)" from the start
68116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)".  The
68275f265fbbbb64ab060bf41c5a4677ce56014ce9fChris Lattner  // only way to do this without lookahead is to eat the '(' and see what is
68375f265fbbbb64ab060bf41c5a4677ce56014ce9fChris Lattner  // after it.
6848c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar  const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext());
68516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  if (getLexer().isNot(AsmToken::LParen)) {
68654482b472a888c9efe003ad694ecf47b21878f0eChris Lattner    SMLoc ExprEnd;
68754482b472a888c9efe003ad694ecf47b21878f0eChris Lattner    if (getParser().ParseExpression(Disp, ExprEnd)) return 0;
688f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
68916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // After parsing the base expression we could either have a parenthesized
69016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // memory address or not.  If not, return now.  If so, eat the (.
69116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    if (getLexer().isNot(AsmToken::LParen)) {
692c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar      // Unless we have a segment register, treat this as an immediate.
693309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner      if (SegReg == 0)
694b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar        return X86Operand::CreateMem(Disp, MemStart, ExprEnd);
6950a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner      return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd);
69616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    }
697f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
69816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // Eat the '('.
699b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
70016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  } else {
70116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // Okay, we have a '('.  We don't know if this is an expression or not, but
70216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // so we have to eat the ( to see beyond it.
70318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    SMLoc LParenLoc = Parser.getTok().getLoc();
704b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat the '('.
705f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
7067b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby    if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) {
70716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // Nothing to do here, fall into the code below with the '(' part of the
70816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // memory operand consumed.
70916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    } else {
710b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner      SMLoc ExprEnd;
711f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
71216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // It must be an parenthesized expression, parse it now.
713b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner      if (getParser().ParseParenExpression(Disp, ExprEnd))
714309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        return 0;
715f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
71616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // After parsing the base expression we could either have a parenthesized
71716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // memory address or not.  If not, return now.  If so, eat the (.
71816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      if (getLexer().isNot(AsmToken::LParen)) {
719c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar        // Unless we have a segment register, treat this as an immediate.
720309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        if (SegReg == 0)
721b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar          return X86Operand::CreateMem(Disp, LParenLoc, ExprEnd);
7220a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner        return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd);
72316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      }
724f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
72516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // Eat the '('.
726b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();
72716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    }
72816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
729f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
73016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  // If we reached here, then we just ate the ( of the memory operand.  Process
73116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  // the rest of the memory operand.
732022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
733f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
73429ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner  if (getLexer().is(AsmToken::Percent)) {
7355efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer    SMLoc StartLoc, EndLoc;
7365efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer    if (ParseRegister(BaseReg, StartLoc, EndLoc)) return 0;
7373c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes    if (BaseReg == X86::EIZ || BaseReg == X86::RIZ) {
7385efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer      Error(StartLoc, "eiz and riz can only be used as index registers",
7395efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer            SMRange(StartLoc, EndLoc));
7403c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes      return 0;
7413c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes    }
74229ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner  }
743f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
74416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  if (getLexer().is(AsmToken::Comma)) {
745b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat the comma.
74616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
74716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // Following the comma we should have either an index register, or a scale
74816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // value. We don't support the later form, but we want to parse it
74916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // correctly.
75016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    //
75116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // Not that even though it would be completely consistent to support syntax
7523c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes    // like "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this.
7537b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby    if (getLexer().is(AsmToken::Percent)) {
75429ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner      SMLoc L;
75529ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner      if (ParseRegister(IndexReg, L, L)) return 0;
756f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
75716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      if (getLexer().isNot(AsmToken::RParen)) {
75816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar        // Parse the scale amount:
75916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar        //  ::= ',' [scale-expression]
760309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        if (getLexer().isNot(AsmToken::Comma)) {
76118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan          Error(Parser.getTok().getLoc(),
762309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner                "expected comma in scale expression");
763309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner          return 0;
764309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        }
765b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan        Parser.Lex(); // Eat the comma.
76616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
76716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar        if (getLexer().isNot(AsmToken::RParen)) {
76818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan          SMLoc Loc = Parser.getTok().getLoc();
76916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
77016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar          int64_t ScaleVal;
77116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar          if (getParser().ParseAbsoluteExpression(ScaleVal))
772309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner            return 0;
773f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
77416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar          // Validate the scale amount.
775309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner          if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8){
776309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner            Error(Loc, "scale factor in address must be 1, 2, 4 or 8");
777309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner            return 0;
778309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner          }
77916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar          Scale = (unsigned)ScaleVal;
78016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar        }
78116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      }
78216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    } else if (getLexer().isNot(AsmToken::RParen)) {
783ee9102587e7f6fc95de9fc5731b341eeb9bfc3caDaniel Dunbar      // A scale amount without an index is ignored.
78416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // index.
78518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan      SMLoc Loc = Parser.getTok().getLoc();
78616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
78716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      int64_t Value;
78816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      if (getParser().ParseAbsoluteExpression(Value))
789309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        return 0;
790f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
791ee9102587e7f6fc95de9fc5731b341eeb9bfc3caDaniel Dunbar      if (Value != 1)
792ee9102587e7f6fc95de9fc5731b341eeb9bfc3caDaniel Dunbar        Warning(Loc, "scale factor without index register is ignored");
793ee9102587e7f6fc95de9fc5731b341eeb9bfc3caDaniel Dunbar      Scale = 1;
79416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    }
79516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
796f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
79716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  // Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
798309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner  if (getLexer().isNot(AsmToken::RParen)) {
79918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    Error(Parser.getTok().getLoc(), "unexpected token in memory operand");
800309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner    return 0;
801309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner  }
80218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  SMLoc MemEnd = Parser.getTok().getLoc();
803b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat the ')'.
804f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
8050a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner  return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale,
8060a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner                               MemStart, MemEnd);
807dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar}
808dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar
809dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patelbool X86AsmParser::
81038e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin KramerParseInstruction(StringRef Name, SMLoc NameLoc,
8119898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner                 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
812693173feefaa326fad0e386470846fb3199ba381Chris Lattner  StringRef PatchedName = Name;
81339e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar
814d8f717911dcdccb1a60b3049ea22c7767970dcb7Chris Lattner  // FIXME: Hack to recognize setneb as setne.
815d8f717911dcdccb1a60b3049ea22c7767970dcb7Chris Lattner  if (PatchedName.startswith("set") && PatchedName.endswith("b") &&
816d8f717911dcdccb1a60b3049ea22c7767970dcb7Chris Lattner      PatchedName != "setb" && PatchedName != "setnb")
817d8f717911dcdccb1a60b3049ea22c7767970dcb7Chris Lattner    PatchedName = PatchedName.substr(0, Name.size()-1);
818d8f717911dcdccb1a60b3049ea22c7767970dcb7Chris Lattner
81939e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar  // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}.
82039e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar  const MCExpr *ExtraImmOp = 0;
821428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes  if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) &&
82239e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      (PatchedName.endswith("ss") || PatchedName.endswith("sd") ||
82339e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar       PatchedName.endswith("ps") || PatchedName.endswith("pd"))) {
824428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes    bool IsVCMP = PatchedName.startswith("vcmp");
825428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes    unsigned SSECCIdx = IsVCMP ? 4 : 3;
82639e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar    unsigned SSEComparisonCode = StringSwitch<unsigned>(
827428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes      PatchedName.slice(SSECCIdx, PatchedName.size() - 2))
828cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("eq",          0)
829cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("lt",          1)
830cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("le",          2)
831cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("unord",       3)
832cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("neq",         4)
833cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("nlt",         5)
834cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("nle",         6)
835cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("ord",         7)
836cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("eq_uq",       8)
837cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("nge",         9)
838cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("ngt",      0x0A)
839cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("false",    0x0B)
840cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("neq_oq",   0x0C)
841cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("ge",       0x0D)
842cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("gt",       0x0E)
843cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("true",     0x0F)
844cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("eq_os",    0x10)
845cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("lt_oq",    0x11)
846cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("le_oq",    0x12)
847cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("unord_s",  0x13)
848cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("neq_us",   0x14)
849cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("nlt_uq",   0x15)
850cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("nle_uq",   0x16)
851cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("ord_s",    0x17)
852cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("eq_us",    0x18)
853cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("nge_uq",   0x19)
854cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("ngt_uq",   0x1A)
855cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("false_os", 0x1B)
856cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("neq_os",   0x1C)
857cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("ge_oq",    0x1D)
858cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("gt_oq",    0x1E)
859cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("true_us",  0x1F)
86039e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      .Default(~0U);
86139e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar    if (SSEComparisonCode != ~0U) {
86239e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      ExtraImmOp = MCConstantExpr::Create(SSEComparisonCode,
86339e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar                                          getParser().getContext());
86439e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      if (PatchedName.endswith("ss")) {
865428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes        PatchedName = IsVCMP ? "vcmpss" : "cmpss";
86639e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      } else if (PatchedName.endswith("sd")) {
867428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes        PatchedName = IsVCMP ? "vcmpsd" : "cmpsd";
86839e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      } else if (PatchedName.endswith("ps")) {
869428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes        PatchedName = IsVCMP ? "vcmpps" : "cmpps";
87039e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      } else {
87139e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar        assert(PatchedName.endswith("pd") && "Unexpected mnemonic!");
872428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes        PatchedName = IsVCMP ? "vcmppd" : "cmppd";
87339e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      }
87439e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar    }
87539e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar  }
876f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes
8771b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar  Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
87816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
87939e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar  if (ExtraImmOp)
88039e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar    Operands.push_back(X86Operand::CreateImm(ExtraImmOp, NameLoc, NameLoc));
881c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
882c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
8832544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  // Determine whether this is an instruction prefix.
8842544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  bool isPrefix =
885693173feefaa326fad0e386470846fb3199ba381Chris Lattner    Name == "lock" || Name == "rep" ||
886693173feefaa326fad0e386470846fb3199ba381Chris Lattner    Name == "repe" || Name == "repz" ||
887beb6898df8f96ccea4ae147587479b507bb3e491Rafael Espindola    Name == "repne" || Name == "repnz" ||
888bfd2d26159c87262fcf462ea442f99478a2093c9Rafael Espindola    Name == "rex64" || Name == "data16";
889c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
890c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
8912544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  // This does the actual operand parsing.  Don't parse any more if we have a
8922544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we
8932544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  // just want to parse the "lock" as the first instruction and the "incl" as
8942544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  // the next one.
8952544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  if (getLexer().isNot(AsmToken::EndOfStatement) && !isPrefix) {
8960db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar
8970db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar    // Parse '*' modifier.
8980db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar    if (getLexer().is(AsmToken::Star)) {
89918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan      SMLoc Loc = Parser.getTok().getLoc();
900b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner      Operands.push_back(X86Operand::CreateToken("*", Loc));
901b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex(); // Eat the star.
9020db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar    }
9030db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar
90416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // Read the first operand.
905309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner    if (X86Operand *Op = ParseOperand())
906309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner      Operands.push_back(Op);
907cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    else {
908cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      Parser.EatToEndOfStatement();
90916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      return true;
910cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    }
91139e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar
91216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    while (getLexer().is(AsmToken::Comma)) {
913b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();  // Eat the comma.
91416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
91516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // Parse and remember the operand.
916309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner      if (X86Operand *Op = ParseOperand())
917309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        Operands.push_back(Op);
918cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      else {
919cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        Parser.EatToEndOfStatement();
92016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar        return true;
921cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      }
92216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    }
923c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
924cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    if (getLexer().isNot(AsmToken::EndOfStatement)) {
925c146c4d47a7ec54c14e730c30bea821c34dc4c48Chris Lattner      SMLoc Loc = getLexer().getLoc();
926cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      Parser.EatToEndOfStatement();
927c146c4d47a7ec54c14e730c30bea821c34dc4c48Chris Lattner      return Error(Loc, "unexpected token in argument list");
928cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    }
92916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
930c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
9312544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  if (getLexer().is(AsmToken::EndOfStatement))
9322544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner    Parser.Lex(); // Consume the EndOfStatement
93376331754d4a06e2394c15ae8f4870f4aeaf5ca1fKevin Enderby  else if (isPrefix && getLexer().is(AsmToken::Slash))
93476331754d4a06e2394c15ae8f4870f4aeaf5ca1fKevin Enderby    Parser.Lex(); // Consume the prefix separator Slash
93516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
93698c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner  // This is a terrible hack to handle "out[bwl]? %al, (%dx)" ->
93798c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner  // "outb %al, %dx".  Out doesn't take a memory form, but this is a widely
93898c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner  // documented form in various unofficial manuals, so a lot of code uses it.
93998c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner  if ((Name == "outb" || Name == "outw" || Name == "outl" || Name == "out") &&
94098c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      Operands.size() == 3) {
94198c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner    X86Operand &Op = *(X86Operand*)Operands.back();
94298c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner    if (Op.isMem() && Op.Mem.SegReg == 0 &&
94398c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner        isa<MCConstantExpr>(Op.Mem.Disp) &&
94498c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner        cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
94598c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner        Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
94698c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      SMLoc Loc = Op.getEndLoc();
94798c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      Operands.back() = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
94898c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      delete &Op;
94998c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner    }
95098c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner  }
95100743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger  // Same hack for "in[bwl]? (%dx), %al" -> "inb %dx, %al".
95200743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger  if ((Name == "inb" || Name == "inw" || Name == "inl" || Name == "in") &&
95300743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger      Operands.size() == 3) {
95400743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger    X86Operand &Op = *(X86Operand*)Operands.begin()[1];
95500743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger    if (Op.isMem() && Op.Mem.SegReg == 0 &&
95600743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger        isa<MCConstantExpr>(Op.Mem.Disp) &&
95700743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger        cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
95800743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger        Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
95900743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger      SMLoc Loc = Op.getEndLoc();
96000743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger      Operands.begin()[1] = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
96100743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger      delete &Op;
96200743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger    }
96300743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger  }
96496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  // Transform "ins[bwl] %dx, %es:(%edi)" into "ins[bwl]"
96596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  if (Name.startswith("ins") && Operands.size() == 3 &&
96696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      (Name == "insb" || Name == "insw" || Name == "insl")) {
96796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand &Op = *(X86Operand*)Operands.begin()[1];
96896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand &Op2 = *(X86Operand*)Operands.begin()[2];
96996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    if (Op.isReg() && Op.getReg() == X86::DX && isDstOp(Op2)) {
97096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      Operands.pop_back();
97196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      Operands.pop_back();
97296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      delete &Op;
97396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      delete &Op2;
97496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    }
97596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  }
97696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger
97796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  // Transform "outs[bwl] %ds:(%esi), %dx" into "out[bwl]"
97896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  if (Name.startswith("outs") && Operands.size() == 3 &&
97996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      (Name == "outsb" || Name == "outsw" || Name == "outsl")) {
98096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand &Op = *(X86Operand*)Operands.begin()[1];
98196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand &Op2 = *(X86Operand*)Operands.begin()[2];
98296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    if (isSrcOp(Op) && Op2.isReg() && Op2.getReg() == X86::DX) {
98396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      Operands.pop_back();
98496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      Operands.pop_back();
98596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      delete &Op;
98696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      delete &Op2;
98796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    }
98896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  }
98996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger
99096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  // Transform "movs[bwl] %ds:(%esi), %es:(%edi)" into "movs[bwl]"
99196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  if (Name.startswith("movs") && Operands.size() == 3 &&
99296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      (Name == "movsb" || Name == "movsw" || Name == "movsl" ||
99359ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng       (is64BitMode() && Name == "movsq"))) {
99496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand &Op = *(X86Operand*)Operands.begin()[1];
99596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand &Op2 = *(X86Operand*)Operands.begin()[2];
99696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    if (isSrcOp(Op) && isDstOp(Op2)) {
99796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      Operands.pop_back();
99896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      Operands.pop_back();
99996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      delete &Op;
100096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      delete &Op2;
100196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    }
100296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  }
100396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  // Transform "lods[bwl] %ds:(%esi),{%al,%ax,%eax,%rax}" into "lods[bwl]"
100496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  if (Name.startswith("lods") && Operands.size() == 3 &&
100596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      (Name == "lods" || Name == "lodsb" || Name == "lodsw" ||
100659ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng       Name == "lodsl" || (is64BitMode() && Name == "lodsq"))) {
100796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]);
100896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand *Op2 = static_cast<X86Operand*>(Operands[2]);
100996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    if (isSrcOp(*Op1) && Op2->isReg()) {
101096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      const char *ins;
101196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      unsigned reg = Op2->getReg();
101296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      bool isLods = Name == "lods";
101396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      if (reg == X86::AL && (isLods || Name == "lodsb"))
101496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = "lodsb";
101596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      else if (reg == X86::AX && (isLods || Name == "lodsw"))
101696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = "lodsw";
101796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      else if (reg == X86::EAX && (isLods || Name == "lodsl"))
101896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = "lodsl";
101996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      else if (reg == X86::RAX && (isLods || Name == "lodsq"))
102096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = "lodsq";
102196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      else
102296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = NULL;
102396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      if (ins != NULL) {
102496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        Operands.pop_back();
102596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        Operands.pop_back();
102696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        delete Op1;
102796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        delete Op2;
102896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        if (Name != ins)
102996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger          static_cast<X86Operand*>(Operands[0])->setTokenValue(ins);
103096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      }
103196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    }
103296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  }
103396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  // Transform "stos[bwl] {%al,%ax,%eax,%rax},%es:(%edi)" into "stos[bwl]"
103496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  if (Name.startswith("stos") && Operands.size() == 3 &&
103596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      (Name == "stos" || Name == "stosb" || Name == "stosw" ||
103659ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng       Name == "stosl" || (is64BitMode() && Name == "stosq"))) {
103796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]);
103896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand *Op2 = static_cast<X86Operand*>(Operands[2]);
103996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    if (isDstOp(*Op2) && Op1->isReg()) {
104096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      const char *ins;
104196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      unsigned reg = Op1->getReg();
104296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      bool isStos = Name == "stos";
104396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      if (reg == X86::AL && (isStos || Name == "stosb"))
104496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = "stosb";
104596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      else if (reg == X86::AX && (isStos || Name == "stosw"))
104696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = "stosw";
104796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      else if (reg == X86::EAX && (isStos || Name == "stosl"))
104896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = "stosl";
104996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      else if (reg == X86::RAX && (isStos || Name == "stosq"))
105096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = "stosq";
105196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      else
105296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = NULL;
105396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      if (ins != NULL) {
105496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        Operands.pop_back();
105596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        Operands.pop_back();
105696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        delete Op1;
105796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        delete Op2;
105896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        if (Name != ins)
105996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger          static_cast<X86Operand*>(Operands[0])->setTokenValue(ins);
106096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      }
106196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    }
106296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  }
106396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger
1064e9e16a36d9ff355dab60e4b95673bf7a0cd27e86Chris Lattner  // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>.  Canonicalize to
1065ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner  // "shift <op>".
1066d5e7705a05947e60806b795880f09757e835f590Daniel Dunbar  if ((Name.startswith("shr") || Name.startswith("sar") ||
10678c24b0c6996a8f03ff32766f0695dcf19577af59Chris Lattner       Name.startswith("shl") || Name.startswith("sal") ||
10688c24b0c6996a8f03ff32766f0695dcf19577af59Chris Lattner       Name.startswith("rcl") || Name.startswith("rcr") ||
10698c24b0c6996a8f03ff32766f0695dcf19577af59Chris Lattner       Name.startswith("rol") || Name.startswith("ror")) &&
107047ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner      Operands.size() == 3) {
107147ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner    X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]);
107247ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner    if (Op1->isImm() && isa<MCConstantExpr>(Op1->getImm()) &&
107347ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner        cast<MCConstantExpr>(Op1->getImm())->getValue() == 1) {
107447ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner      delete Operands[1];
107547ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner      Operands.erase(Operands.begin() + 1);
107647ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner    }
1077f2de13f8d7bed958538bbd9dbeb9b15ea48456ccDaniel Dunbar  }
107815f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner
107915f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner  // Transforms "int $3" into "int3" as a size optimization.  We can't write an
108015f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner  // instalias with an immediate operand yet.
108115f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner  if (Name == "int" && Operands.size() == 2) {
108215f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner    X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]);
108315f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner    if (Op1->isImm() && isa<MCConstantExpr>(Op1->getImm()) &&
108415f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner        cast<MCConstantExpr>(Op1->getImm())->getValue() == 3) {
108515f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner      delete Operands[1];
108615f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner      Operands.erase(Operands.begin() + 1);
108715f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner      static_cast<X86Operand*>(Operands[0])->setTokenValue("int3");
108815f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner    }
108915f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner  }
1090c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
10919898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner  return false;
1092a3af370dc12f6d5100da5d614ab0a62da135569aDaniel Dunbar}
1093a3af370dc12f6d5100da5d614ab0a62da135569aDaniel Dunbar
1094dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patelbool X86AsmParser::
10957036f8be4df8a1a830ca01afe9497b035a5647d6Chris LattnerMatchAndEmitInstruction(SMLoc IDLoc,
10967c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner                        SmallVectorImpl<MCParsedAsmOperand*> &Operands,
10977036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner                        MCStreamer &Out) {
1098f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar  assert(!Operands.empty() && "Unexpect empty operand list!");
10997c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner  X86Operand *Op = static_cast<X86Operand*>(Operands[0]);
11007c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner  assert(Op->isToken() && "Leading operand should always be a mnemonic!");
11017c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner
11027c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner  // First, handle aliases that expand to multiple instructions.
11037c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner  // FIXME: This should be replaced with a real .td file alias mechanism.
110490fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner  // Also, MatchInstructionImpl should do actually *do* the EmitInstruction
110590fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner  // call.
11060966ec08610c02c8556105f2fff88a7e7247a549Andrew Trick  if (Op->getToken() == "fstsw" || Op->getToken() == "fstcw" ||
11078b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner      Op->getToken() == "fstsww" || Op->getToken() == "fstcww" ||
1108905f2e06691672c236ae864faf0ad7220afc2844Chris Lattner      Op->getToken() == "finit" || Op->getToken() == "fsave" ||
11095a378076a44ef3f507b91aa8e7715fabaec42074Kevin Enderby      Op->getToken() == "fstenv" || Op->getToken() == "fclex") {
11107c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner    MCInst Inst;
11117c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner    Inst.setOpcode(X86::WAIT);
11127c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner    Out.EmitInstruction(Inst);
1113f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar
11140bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner    const char *Repl =
11150bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner      StringSwitch<const char*>(Op->getToken())
11168b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner        .Case("finit",  "fninit")
11178b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner        .Case("fsave",  "fnsave")
11188b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner        .Case("fstcw",  "fnstcw")
11198b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner        .Case("fstcww",  "fnstcw")
1120905f2e06691672c236ae864faf0ad7220afc2844Chris Lattner        .Case("fstenv", "fnstenv")
11218b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner        .Case("fstsw",  "fnstsw")
11228b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner        .Case("fstsww", "fnstsw")
11238b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner        .Case("fclex",  "fnclex")
11240bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner        .Default(0);
11250bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner    assert(Repl && "Unknown wait-prefixed instruction");
1126b0f96facd6e6637cb71bbeaf2f4e006f0b6348e3Benjamin Kramer    delete Operands[0];
11270bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner    Operands[0] = X86Operand::CreateToken(Repl, IDLoc);
11287c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner  }
1129c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
1130a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  bool WasOriginallyInvalidOperand = false;
1131ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner  unsigned OrigErrorInfo;
11327036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner  MCInst Inst;
1133c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
1134c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // First, try a direct match.
11350a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  switch (MatchInstructionImpl(Operands, Inst, OrigErrorInfo,
11360a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel                               getParser().getAssemblerDialect())) {
113719cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  default: break;
1138ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  case Match_Success:
11397036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner    Out.EmitInstruction(Inst);
1140c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar    return false;
1141ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  case Match_MissingFeature:
1142ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1143ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    return true;
1144b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar  case Match_ConversionFail:
1145b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar    return Error(IDLoc, "unable to convert operands to instruction");
1146a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  case Match_InvalidOperand:
1147a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner    WasOriginallyInvalidOperand = true;
1148a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner    break;
1149a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  case Match_MnemonicFail:
1150ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    break;
1151ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  }
1152c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
1153c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // FIXME: Ideally, we would only attempt suffix matches for things which are
1154c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // valid prefixes, and we could just infer the right unambiguous
1155c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // type. However, that requires substantially more matcher support than the
1156c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // following hack.
1157c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
1158c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // Change the operand to point to a temporary token.
1159c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  StringRef Base = Op->getToken();
1160f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar  SmallString<16> Tmp;
1161f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar  Tmp += Base;
1162f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar  Tmp += ' ';
1163f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar  Op->setTokenValue(Tmp.str());
1164c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
1165fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  // If this instruction starts with an 'f', then it is a floating point stack
1166fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  // instruction.  These come in up to three forms for 32-bit, 64-bit, and
1167fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  // 80-bit floating point, which use the suffixes s,l,t respectively.
1168fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  //
1169fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  // Otherwise, we assume that this may be an integer instruction, which comes
1170fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  // in 8/16/32/64-bit forms using the b,w,l,q suffixes respectively.
1171fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0";
1172fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner
1173c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // Check for the various suffix matches.
1174fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  Tmp[Base.size()] = Suffixes[0];
1175fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  unsigned ErrorInfoIgnore;
117619cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  unsigned Match1, Match2, Match3, Match4;
1177fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner
1178fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  Match1 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore);
1179fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  Tmp[Base.size()] = Suffixes[1];
1180fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  Match2 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore);
1181fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  Tmp[Base.size()] = Suffixes[2];
1182fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  Match3 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore);
1183fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  Tmp[Base.size()] = Suffixes[3];
1184fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  Match4 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore);
1185c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
1186c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // Restore the old token.
1187c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  Op->setTokenValue(Base);
1188c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
1189c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // If exactly one matched, then we treat that as a successful match (and the
1190c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // instruction will already have been filled in correctly, since the failing
1191c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // matches won't have modified it).
1192ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  unsigned NumSuccessfulMatches =
1193fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner    (Match1 == Match_Success) + (Match2 == Match_Success) +
1194fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner    (Match3 == Match_Success) + (Match4 == Match_Success);
11957036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner  if (NumSuccessfulMatches == 1) {
11967036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner    Out.EmitInstruction(Inst);
1197c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar    return false;
11987036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner  }
1199c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
1200ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  // Otherwise, the match failed, try to produce a decent error message.
1201f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar
120209062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar  // If we had multiple suffix matches, then identify this as an ambiguous
120309062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar  // match.
1204ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  if (NumSuccessfulMatches > 1) {
120509062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    char MatchChars[4];
120609062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    unsigned NumMatches = 0;
1207fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner    if (Match1 == Match_Success) MatchChars[NumMatches++] = Suffixes[0];
1208fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner    if (Match2 == Match_Success) MatchChars[NumMatches++] = Suffixes[1];
1209fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner    if (Match3 == Match_Success) MatchChars[NumMatches++] = Suffixes[2];
1210fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner    if (Match4 == Match_Success) MatchChars[NumMatches++] = Suffixes[3];
121109062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar
121209062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    SmallString<126> Msg;
121309062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    raw_svector_ostream OS(Msg);
121409062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    OS << "ambiguous instructions require an explicit suffix (could be ";
121509062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    for (unsigned i = 0; i != NumMatches; ++i) {
121609062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar      if (i != 0)
121709062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar        OS << ", ";
121809062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar      if (i + 1 == NumMatches)
121909062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar        OS << "or ";
122009062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar      OS << "'" << Base << MatchChars[i] << "'";
122109062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    }
122209062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    OS << ")";
122309062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    Error(IDLoc, OS.str());
1224ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    return true;
122509062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar  }
1226c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
1227a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  // Okay, we know that none of the variants matched successfully.
1228c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
1229a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  // If all of the instructions reported an invalid mnemonic, then the original
1230a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  // mnemonic was invalid.
1231fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  if ((Match1 == Match_MnemonicFail) && (Match2 == Match_MnemonicFail) &&
1232fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner      (Match3 == Match_MnemonicFail) && (Match4 == Match_MnemonicFail)) {
1233ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner    if (!WasOriginallyInvalidOperand) {
1234f82edaffb1a6d41bc89d86c69f53962e63621aadBenjamin Kramer      return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'",
1235f82edaffb1a6d41bc89d86c69f53962e63621aadBenjamin Kramer                   Op->getLocRange());
1236ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner    }
1237ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner
1238ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner    // Recover location info for the operand if we know which was the problem.
1239ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner    if (OrigErrorInfo != ~0U) {
1240f884012c93578912556de6ab89ecebab79b4ee31Chris Lattner      if (OrigErrorInfo >= Operands.size())
1241f884012c93578912556de6ab89ecebab79b4ee31Chris Lattner        return Error(IDLoc, "too few operands for instruction");
1242c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
1243d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner      X86Operand *Operand = (X86Operand*)Operands[OrigErrorInfo];
1244d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner      if (Operand->getStartLoc().isValid()) {
1245d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner        SMRange OperandRange = Operand->getLocRange();
1246d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner        return Error(Operand->getStartLoc(), "invalid operand for instruction",
1247d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner                     OperandRange);
1248d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner      }
1249ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner    }
1250ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner
1251d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner    return Error(IDLoc, "invalid operand for instruction");
1252a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  }
1253c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
1254ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  // If one instruction matched with a missing feature, report this as a
1255ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  // missing feature.
1256fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  if ((Match1 == Match_MissingFeature) + (Match2 == Match_MissingFeature) +
1257fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner      (Match3 == Match_MissingFeature) + (Match4 == Match_MissingFeature) == 1){
1258ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1259ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    return true;
1260ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  }
1261c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
1262a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  // If one instruction matched with an invalid operand, report this as an
1263a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  // operand failure.
1264fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  if ((Match1 == Match_InvalidOperand) + (Match2 == Match_InvalidOperand) +
1265fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner      (Match3 == Match_InvalidOperand) + (Match4 == Match_InvalidOperand) == 1){
1266a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner    Error(IDLoc, "invalid operand for instruction");
1267a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner    return true;
1268a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  }
1269c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
1270ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  // If all of these were an outright failure, report it in a useless way.
1271a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  Error(IDLoc, "unknown use of instruction mnemonic without a size suffix");
1272c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  return true;
1273c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar}
1274c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
1275c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
1276dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patelbool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
1277537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner  StringRef IDVal = DirectiveID.getIdentifier();
1278537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner  if (IDVal == ".word")
1279537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner    return ParseDirectiveWord(2, DirectiveID.getLoc());
1280bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng  else if (IDVal.startswith(".code"))
1281bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    return ParseDirectiveCode(IDVal, DirectiveID.getLoc());
1282537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner  return true;
1283537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner}
1284537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner
1285537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner/// ParseDirectiveWord
1286537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner///  ::= .word [ expression (, expression)* ]
1287dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patelbool X86AsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
1288537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1289537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner    for (;;) {
1290537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner      const MCExpr *Value;
1291537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner      if (getParser().ParseExpression(Value))
1292537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner        return true;
1293537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner
1294537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner      getParser().getStreamer().EmitValue(Value, Size, 0 /*addrspace*/);
1295537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner
1296537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner      if (getLexer().is(AsmToken::EndOfStatement))
1297537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner        break;
1298537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner
1299537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner      // FIXME: Improve diagnostic.
1300537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner      if (getLexer().isNot(AsmToken::Comma))
1301537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner        return Error(L, "unexpected token in directive");
1302537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner      Parser.Lex();
1303537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner    }
1304537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner  }
1305537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner
1306537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner  Parser.Lex();
1307537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner  return false;
1308537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner}
1309537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner
1310bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng/// ParseDirectiveCode
1311bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng///  ::= .code32 | .code64
1312dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patelbool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
1313bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng  if (IDVal == ".code32") {
1314bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    Parser.Lex();
1315bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    if (is64BitMode()) {
1316bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng      SwitchMode();
1317bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng      getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
1318bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    }
1319bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng  } else if (IDVal == ".code64") {
1320bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    Parser.Lex();
1321bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    if (!is64BitMode()) {
1322bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng      SwitchMode();
1323bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng      getParser().getStreamer().EmitAssemblerFlag(MCAF_Code64);
1324bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    }
1325bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng  } else {
1326bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    return Error(L, "unexpected directive " + IDVal);
1327bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng  }
1328537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner
1329bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng  return false;
1330bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng}
1331537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner
1332537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner
1333e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callananextern "C" void LLVMInitializeX86AsmLexer();
1334e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan
1335092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar// Force static initialization.
1336092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbarextern "C" void LLVMInitializeX86AsmParser() {
1337dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patel  RegisterMCAsmParser<X86AsmParser> X(TheX86_32Target);
1338dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patel  RegisterMCAsmParser<X86AsmParser> Y(TheX86_64Target);
1339e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan  LLVMInitializeX86AsmLexer();
1340092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar}
13410e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar
13420692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER
13430692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION
13440e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar#include "X86GenAsmMatcher.inc"
1345