X86AsmParser.cpp revision e5e4ff974df52aa870085904b6670c4d22ada0ac
1092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar//===-- X86AsmParser.cpp - Parse X86 assembly to MCInst instructions ------===//
2092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar//
3092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar//                     The LLVM Compiler Infrastructure
4092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar//
5092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar// This file is distributed under the University of Illinois Open Source
6092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar// License. See LICENSE.TXT for details.
7092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar//
8092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar//===----------------------------------------------------------------------===//
9092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar
109898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner#include "llvm/Target/TargetAsmParser.h"
114cb1e13769856716261a4d315f8202bd918502c3Daniel Dunbar#include "X86.h"
12dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar#include "llvm/ADT/SmallVector.h"
131b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar#include "llvm/ADT/StringSwitch.h"
1416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar#include "llvm/ADT/Twine.h"
159c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby#include "llvm/MC/MCStreamer.h"
168c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar#include "llvm/MC/MCExpr.h"
17a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar#include "llvm/MC/MCInst.h"
18c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmLexer.h"
19c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmParser.h"
20c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
2116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar#include "llvm/Support/SourceMgr.h"
22092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar#include "llvm/Target/TargetRegistry.h"
23092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar#include "llvm/Target/TargetAsmParser.h"
24092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbarusing namespace llvm;
25092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar
26092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbarnamespace {
27c6b79ac88e52367dd2afdf03b1be81b10345c0bbBenjamin Kramerstruct X86Operand;
28092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar
2916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbarclass X86ATTAsmParser : public TargetAsmParser {
3016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  MCAsmParser &Parser;
31a2edbabcb86f213eca6daeda5d801f8c7b1e44b2Daniel Dunbar
32f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbarprotected:
33f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar  unsigned Is64Bit : 1;
34f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar
3516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbarprivate:
3616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  MCAsmParser &getParser() const { return Parser; }
37a2edbabcb86f213eca6daeda5d801f8c7b1e44b2Daniel Dunbar
3816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
3916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
4016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }
4116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
4216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
4316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
4429ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
4516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
46309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner  X86Operand *ParseOperand();
47eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner  X86Operand *ParseMemOperand(unsigned SegReg, SMLoc StartLoc);
489c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby
499c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby  bool ParseDirectiveWord(unsigned Size, SMLoc L);
509c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby
51f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar  void InstructionCleanup(MCInst &Inst);
52f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar
530e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar  /// @name Auto-generated Match Functions
54c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  /// {
550e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar
569898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner  bool MatchInstruction(const SmallVectorImpl<MCParsedAsmOperand*> &Operands,
5720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar                        MCInst &Inst);
5820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
59c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  bool MatchInstructionImpl(
60c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar    const SmallVectorImpl<MCParsedAsmOperand*> &Operands, MCInst &Inst);
61c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
620e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar  /// }
6316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
6416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbarpublic:
6516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  X86ATTAsmParser(const Target &T, MCAsmParser &_Parser)
6616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    : TargetAsmParser(T), Parser(_Parser) {}
6716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
68f007e853e26845cd6866b52d646455fc69f4e0afChris Lattner  virtual bool ParseInstruction(const StringRef &Name, SMLoc NameLoc,
699898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner                                SmallVectorImpl<MCParsedAsmOperand*> &Operands);
709c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby
719c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby  virtual bool ParseDirective(AsmToken DirectiveID);
7216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar};
73f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar
74f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbarclass X86_32ATTAsmParser : public X86ATTAsmParser {
75f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbarpublic:
76f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar  X86_32ATTAsmParser(const Target &T, MCAsmParser &_Parser)
77f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar    : X86ATTAsmParser(T, _Parser) {
78f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar    Is64Bit = false;
79f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar  }
80f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar};
81f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar
82f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbarclass X86_64ATTAsmParser : public X86ATTAsmParser {
83f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbarpublic:
84f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar  X86_64ATTAsmParser(const Target &T, MCAsmParser &_Parser)
85f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar    : X86ATTAsmParser(T, _Parser) {
86f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar    Is64Bit = true;
87f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar  }
88f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar};
89f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar
9037dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner} // end anonymous namespace
9137dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner
92e9b466d4f09de3b46c0d0d1e71cabddc7cc9021bSean Callanan/// @name Auto-generated Match Functions
93e9b466d4f09de3b46c0d0d1e71cabddc7cc9021bSean Callanan/// {
94e9b466d4f09de3b46c0d0d1e71cabddc7cc9021bSean Callanan
95b8d6e98e566724f58344d275a4bd675249bb713aChris Lattnerstatic unsigned MatchRegisterName(StringRef Name);
96e9b466d4f09de3b46c0d0d1e71cabddc7cc9021bSean Callanan
97e9b466d4f09de3b46c0d0d1e71cabddc7cc9021bSean Callanan/// }
9837dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner
9937dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattnernamespace {
10016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
10116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar/// X86Operand - Instances of this class represent a parsed X86 machine
10216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar/// instruction.
10345220a84394758c86cc29ee0e3fe6738946fbcd0Chris Lattnerstruct X86Operand : public MCParsedAsmOperand {
1041f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner  enum KindTy {
10520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    Token,
10616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    Register,
10716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    Immediate,
10816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    Memory
10916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  } Kind;
11016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
11129ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner  SMLoc StartLoc, EndLoc;
11229ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner
11316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  union {
11416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    struct {
11520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar      const char *Data;
11620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar      unsigned Length;
11720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    } Tok;
11820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
11920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    struct {
12016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      unsigned RegNo;
12116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    } Reg;
12216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
12316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    struct {
1248c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar      const MCExpr *Val;
12516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    } Imm;
12616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
12716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    struct {
12816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      unsigned SegReg;
1298c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar      const MCExpr *Disp;
13016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      unsigned BaseReg;
13116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      unsigned IndexReg;
13216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      unsigned Scale;
13316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    } Mem;
134dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar  };
13516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
1360a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner  X86Operand(KindTy K, SMLoc Start, SMLoc End)
1371f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner    : Kind(K), StartLoc(Start), EndLoc(End) {}
138c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
1391f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner  /// getStartLoc - Get the location of the first token of this operand.
1401f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner  SMLoc getStartLoc() const { return StartLoc; }
1411f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner  /// getEndLoc - Get the location of the last token of this operand.
1421f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner  SMLoc getEndLoc() const { return EndLoc; }
1431f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner
14420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  StringRef getToken() const {
14520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    assert(Kind == Token && "Invalid access!");
14620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    return StringRef(Tok.Data, Tok.Length);
14720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  }
148c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  void setTokenValue(StringRef Value) {
149c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar    assert(Kind == Token && "Invalid access!");
150c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar    Tok.Data = Value.data();
151c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar    Tok.Length = Value.size();
152c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  }
15320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
15416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  unsigned getReg() const {
15516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    assert(Kind == Register && "Invalid access!");
15616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    return Reg.RegNo;
15716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
15816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
1598c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar  const MCExpr *getImm() const {
160022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Immediate && "Invalid access!");
161022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Imm.Val;
162022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
163022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar
1648c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar  const MCExpr *getMemDisp() const {
165022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Memory && "Invalid access!");
166022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Mem.Disp;
167022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
168022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  unsigned getMemSegReg() const {
169022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Memory && "Invalid access!");
170022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Mem.SegReg;
171022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
172022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  unsigned getMemBaseReg() const {
173022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Memory && "Invalid access!");
174022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Mem.BaseReg;
175022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
176022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  unsigned getMemIndexReg() const {
177022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Memory && "Invalid access!");
178022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Mem.IndexReg;
179022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
180022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  unsigned getMemScale() const {
181022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Memory && "Invalid access!");
182022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Mem.Scale;
183022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
184022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar
185a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  bool isToken() const {return Kind == Token; }
18620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
18720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  bool isImm() const { return Kind == Immediate; }
18820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
1895fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar  bool isImmSExt8() const {
1905fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar    // Accept immediates which fit in 8 bits when sign extended, and
1915fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar    // non-absolute immediates.
1925fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar    if (!isImm())
1935fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar      return false;
1945fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar
1958c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm())) {
1968c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar      int64_t Value = CE->getValue();
1978c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar      return Value == (int64_t) (int8_t) Value;
1988c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar    }
1995fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar
2008c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar    return true;
2015fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar  }
2025fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar
20320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  bool isMem() const { return Kind == Memory; }
20420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
205b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  bool isAbsMem() const {
206b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
2077b9147afa7d1875353e1c1347b6b6cf71f548229Daniel Dunbar      !getMemIndexReg() && getMemScale() == 1;
208b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  }
209b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar
210ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar  bool isNoSegMem() const {
211ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar    return Kind == Memory && !getMemSegReg();
212ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar  }
213ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar
21420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  bool isReg() const { return Kind == Register; }
21520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
2169c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
2179c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar    // Add as immediates when possible.
2189c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
2199c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
2209c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar    else
2219c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar      Inst.addOperand(MCOperand::CreateExpr(Expr));
2229c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar  }
2239c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar
2245c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar  void addRegOperands(MCInst &Inst, unsigned N) const {
22520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    assert(N == 1 && "Invalid number of operands!");
22620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getReg()));
22720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  }
22820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
2295c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar  void addImmOperands(MCInst &Inst, unsigned N) const {
23020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    assert(N == 1 && "Invalid number of operands!");
2319c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar    addExpr(Inst, getImm());
23220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  }
23320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
2345c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar  void addImmSExt8Operands(MCInst &Inst, unsigned N) const {
2355fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar    // FIXME: Support user customization of the render method.
2365fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar    assert(N == 1 && "Invalid number of operands!");
2379c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar    addExpr(Inst, getImm());
2385fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar  }
2395fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar
2405c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar  void addMemOperands(MCInst &Inst, unsigned N) const {
241ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar    assert((N == 5) && "Invalid number of operands!");
24220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
24320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    Inst.addOperand(MCOperand::CreateImm(getMemScale()));
24420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemIndexReg()));
2459c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar    addExpr(Inst, getMemDisp());
246ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
247ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar  }
248ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar
249b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  void addAbsMemOperands(MCInst &Inst, unsigned N) const {
250b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    assert((N == 1) && "Invalid number of operands!");
251b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    Inst.addOperand(MCOperand::CreateExpr(getMemDisp()));
252b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  }
253b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar
254ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar  void addNoSegMemOperands(MCInst &Inst, unsigned N) const {
255ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar    assert((N == 4) && "Invalid number of operands!");
256ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
257ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar    Inst.addOperand(MCOperand::CreateImm(getMemScale()));
258ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemIndexReg()));
2599c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar    addExpr(Inst, getMemDisp());
26020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  }
26120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
262b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner  static X86Operand *CreateToken(StringRef Str, SMLoc Loc) {
263b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner    X86Operand *Res = new X86Operand(Token, Loc, Loc);
26429ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Tok.Data = Str.data();
26529ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Tok.Length = Str.size();
26620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    return Res;
26720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  }
26820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
26929ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner  static X86Operand *CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc) {
2701f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner    X86Operand *Res = new X86Operand(Register, StartLoc, EndLoc);
27129ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Reg.RegNo = RegNo;
27229ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    return Res;
27316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
27420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
275b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner  static X86Operand *CreateImm(const MCExpr *Val, SMLoc StartLoc, SMLoc EndLoc){
276b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner    X86Operand *Res = new X86Operand(Immediate, StartLoc, EndLoc);
27729ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Imm.Val = Val;
27829ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    return Res;
27916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
28020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
281b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  /// Create an absolute memory operand.
282b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  static X86Operand *CreateMem(const MCExpr *Disp, SMLoc StartLoc,
283b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar                               SMLoc EndLoc) {
284b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc);
285b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    Res->Mem.SegReg   = 0;
286b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    Res->Mem.Disp     = Disp;
287b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    Res->Mem.BaseReg  = 0;
288b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    Res->Mem.IndexReg = 0;
2897b9147afa7d1875353e1c1347b6b6cf71f548229Daniel Dunbar    Res->Mem.Scale    = 1;
290b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    return Res;
291b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  }
292b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar
293b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  /// Create a generalized memory operand.
294309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner  static X86Operand *CreateMem(unsigned SegReg, const MCExpr *Disp,
295309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner                               unsigned BaseReg, unsigned IndexReg,
2960a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner                               unsigned Scale, SMLoc StartLoc, SMLoc EndLoc) {
297b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    // We should never just have a displacement, that should be parsed as an
298b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    // absolute memory operand.
299c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar    assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
300c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar
301022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    // The scale should always be one of {1,2,4,8}.
302022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
30316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar           "Invalid scale!");
3040a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner    X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc);
30529ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Mem.SegReg   = SegReg;
30629ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Mem.Disp     = Disp;
30729ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Mem.BaseReg  = BaseReg;
30829ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Mem.IndexReg = IndexReg;
30929ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Mem.Scale    = Scale;
31029ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    return Res;
31116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
31216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar};
31316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
31437dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner} // end anonymous namespace.
31516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
31616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
31729ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattnerbool X86ATTAsmParser::ParseRegister(unsigned &RegNo,
31829ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner                                    SMLoc &StartLoc, SMLoc &EndLoc) {
31923075746a1418f281bc2a088ea85560bfd833599Chris Lattner  RegNo = 0;
32018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &TokPercent = Parser.getTok();
3217b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby  assert(TokPercent.is(AsmToken::Percent) && "Invalid token kind!");
32229ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner  StartLoc = TokPercent.getLoc();
323b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat percent token.
3247b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby
32518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
3260d6cd00dbe58b456d0d33663e6a36c270aad2b5aKevin Enderby  if (Tok.isNot(AsmToken::Identifier))
3270d6cd00dbe58b456d0d33663e6a36c270aad2b5aKevin Enderby    return Error(Tok.getLoc(), "invalid register name");
32816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
3290e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar  // FIXME: Validate register for the current architecture; we have to do
3300e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar  // validation later, so maybe there is no need for this here.
3317b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby  RegNo = MatchRegisterName(Tok.getString());
332b8d6e98e566724f58344d275a4bd675249bb713aChris Lattner
333e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner  // Parse %st(1) and "%st" as "%st(0)"
334e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner  if (RegNo == 0 && Tok.getString() == "st") {
335e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    RegNo = X86::ST0;
336e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    EndLoc = Tok.getLoc();
337e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    Parser.Lex(); // Eat 'st'
338e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner
339e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    // Check to see if we have '(4)' after %st.
340e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    if (getLexer().isNot(AsmToken::LParen))
341e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner      return false;
342e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    // Lex the paren.
343e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    getParser().Lex();
344e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner
345e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    const AsmToken &IntTok = Parser.getTok();
346e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    if (IntTok.isNot(AsmToken::Integer))
347e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner      return Error(IntTok.getLoc(), "expected stack index");
348e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    switch (IntTok.getIntVal()) {
349e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 0: RegNo = X86::ST0; break;
350e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 1: RegNo = X86::ST1; break;
351e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 2: RegNo = X86::ST2; break;
352e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 3: RegNo = X86::ST3; break;
353e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 4: RegNo = X86::ST4; break;
354e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 5: RegNo = X86::ST5; break;
355e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 6: RegNo = X86::ST6; break;
356e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 7: RegNo = X86::ST7; break;
357e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    default: return Error(IntTok.getLoc(), "invalid stack index");
358e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    }
359e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner
360e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    if (getParser().Lex().isNot(AsmToken::RParen))
361e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner      return Error(Parser.getTok().getLoc(), "expected ')'");
362e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner
363e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    EndLoc = Tok.getLoc();
364e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    Parser.Lex(); // Eat ')'
365e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    return false;
366e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner  }
367e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner
368245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar  if (RegNo == 0)
3690e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar    return Error(Tok.getLoc(), "invalid register name");
3700e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar
37129ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner  EndLoc = Tok.getLoc();
372b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat identifier token.
37316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  return false;
374092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar}
375092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar
376309264d1e4c41923ff04fb6786749185cf3b9de1Chris LattnerX86Operand *X86ATTAsmParser::ParseOperand() {
37716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  switch (getLexer().getKind()) {
37816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  default:
379eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    // Parse a memory operand with no segment register.
380eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    return ParseMemOperand(0, Parser.getTok().getLoc());
38123075746a1418f281bc2a088ea85560bfd833599Chris Lattner  case AsmToken::Percent: {
382eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    // Read the register.
38323075746a1418f281bc2a088ea85560bfd833599Chris Lattner    unsigned RegNo;
38429ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    SMLoc Start, End;
38529ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    if (ParseRegister(RegNo, Start, End)) return 0;
386eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner
387eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    // If this is a segment register followed by a ':', then this is the start
388eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    // of a memory reference, otherwise this is a normal register reference.
389eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    if (getLexer().isNot(AsmToken::Colon))
390eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner      return X86Operand::CreateReg(RegNo, Start, End);
391eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner
392eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner
393eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    getParser().Lex(); // Eat the colon.
394eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    return ParseMemOperand(RegNo, Start);
39523075746a1418f281bc2a088ea85560bfd833599Chris Lattner  }
39616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  case AsmToken::Dollar: {
39716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // $42 -> immediate.
39818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    SMLoc Start = Parser.getTok().getLoc(), End;
399b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
4008c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar    const MCExpr *Val;
40154482b472a888c9efe003ad694ecf47b21878f0eChris Lattner    if (getParser().ParseExpression(Val, End))
402309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner      return 0;
403b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner    return X86Operand::CreateImm(Val, Start, End);
40416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
40516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
40616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar}
40716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
408eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner/// ParseMemOperand: segment: disp(basereg, indexreg, scale).  The '%ds:' prefix
409eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner/// has already been parsed if present.
410eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris LattnerX86Operand *X86ATTAsmParser::ParseMemOperand(unsigned SegReg, SMLoc MemStart) {
411eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner
41216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  // We have to disambiguate a parenthesized expression "(4+5)" from the start
41316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)".  The
41475f265fbbbb64ab060bf41c5a4677ce56014ce9fChris Lattner  // only way to do this without lookahead is to eat the '(' and see what is
41575f265fbbbb64ab060bf41c5a4677ce56014ce9fChris Lattner  // after it.
4168c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar  const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext());
41716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  if (getLexer().isNot(AsmToken::LParen)) {
41854482b472a888c9efe003ad694ecf47b21878f0eChris Lattner    SMLoc ExprEnd;
41954482b472a888c9efe003ad694ecf47b21878f0eChris Lattner    if (getParser().ParseExpression(Disp, ExprEnd)) return 0;
42016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
42116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // After parsing the base expression we could either have a parenthesized
42216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // memory address or not.  If not, return now.  If so, eat the (.
42316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    if (getLexer().isNot(AsmToken::LParen)) {
424c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar      // Unless we have a segment register, treat this as an immediate.
425309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner      if (SegReg == 0)
426b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar        return X86Operand::CreateMem(Disp, MemStart, ExprEnd);
4270a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner      return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd);
42816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    }
42916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
43016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // Eat the '('.
431b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
43216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  } else {
43316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // Okay, we have a '('.  We don't know if this is an expression or not, but
43416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // so we have to eat the ( to see beyond it.
43518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    SMLoc LParenLoc = Parser.getTok().getLoc();
436b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat the '('.
43716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
4387b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby    if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) {
43916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // Nothing to do here, fall into the code below with the '(' part of the
44016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // memory operand consumed.
44116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    } else {
442b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner      SMLoc ExprEnd;
443b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner
44416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // It must be an parenthesized expression, parse it now.
445b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner      if (getParser().ParseParenExpression(Disp, ExprEnd))
446309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        return 0;
44716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
44816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // After parsing the base expression we could either have a parenthesized
44916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // memory address or not.  If not, return now.  If so, eat the (.
45016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      if (getLexer().isNot(AsmToken::LParen)) {
451c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar        // Unless we have a segment register, treat this as an immediate.
452309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        if (SegReg == 0)
453b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar          return X86Operand::CreateMem(Disp, LParenLoc, ExprEnd);
4540a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner        return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd);
45516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      }
45616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
45716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // Eat the '('.
458b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();
45916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    }
46016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
46116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
46216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  // If we reached here, then we just ate the ( of the memory operand.  Process
46316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  // the rest of the memory operand.
464022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
46516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
46629ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner  if (getLexer().is(AsmToken::Percent)) {
46729ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    SMLoc L;
46829ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    if (ParseRegister(BaseReg, L, L)) return 0;
46929ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner  }
47016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
47116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  if (getLexer().is(AsmToken::Comma)) {
472b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat the comma.
47316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
47416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // Following the comma we should have either an index register, or a scale
47516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // value. We don't support the later form, but we want to parse it
47616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // correctly.
47716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    //
47816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // Not that even though it would be completely consistent to support syntax
47916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // like "1(%eax,,1)", the assembler doesn't.
4807b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby    if (getLexer().is(AsmToken::Percent)) {
48129ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner      SMLoc L;
48229ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner      if (ParseRegister(IndexReg, L, L)) return 0;
48316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
48416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      if (getLexer().isNot(AsmToken::RParen)) {
48516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar        // Parse the scale amount:
48616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar        //  ::= ',' [scale-expression]
487309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        if (getLexer().isNot(AsmToken::Comma)) {
48818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan          Error(Parser.getTok().getLoc(),
489309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner                "expected comma in scale expression");
490309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner          return 0;
491309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        }
492b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan        Parser.Lex(); // Eat the comma.
49316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
49416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar        if (getLexer().isNot(AsmToken::RParen)) {
49518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan          SMLoc Loc = Parser.getTok().getLoc();
49616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
49716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar          int64_t ScaleVal;
49816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar          if (getParser().ParseAbsoluteExpression(ScaleVal))
499309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner            return 0;
50016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
50116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar          // Validate the scale amount.
502309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner          if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8){
503309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner            Error(Loc, "scale factor in address must be 1, 2, 4 or 8");
504309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner            return 0;
505309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner          }
50616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar          Scale = (unsigned)ScaleVal;
50716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar        }
50816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      }
50916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    } else if (getLexer().isNot(AsmToken::RParen)) {
51016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // Otherwise we have the unsupported form of a scale amount without an
51116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // index.
51218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan      SMLoc Loc = Parser.getTok().getLoc();
51316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
51416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      int64_t Value;
51516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      if (getParser().ParseAbsoluteExpression(Value))
516309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        return 0;
51716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
518309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner      Error(Loc, "cannot have scale factor without index register");
519309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner      return 0;
52016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    }
52116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
52216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
52316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  // Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
524309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner  if (getLexer().isNot(AsmToken::RParen)) {
52518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    Error(Parser.getTok().getLoc(), "unexpected token in memory operand");
526309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner    return 0;
527309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner  }
52818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  SMLoc MemEnd = Parser.getTok().getLoc();
529b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat the ')'.
53016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
5310a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner  return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale,
5320a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner                               MemStart, MemEnd);
533dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar}
534dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar
5359898671a74d3fc924347e679c45edaa685b3fe6eChris Lattnerbool X86ATTAsmParser::
5369898671a74d3fc924347e679c45edaa685b3fe6eChris LattnerParseInstruction(const StringRef &Name, SMLoc NameLoc,
5379898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner                 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
538e5e4ff974df52aa870085904b6670c4d22ada0acDan Gohman  // The various flavors of pushf and popf use Requires<In32BitMode> and
539e5e4ff974df52aa870085904b6670c4d22ada0acDan Gohman  // Requires<In64BitMode>, but the assembler doesn't yet implement that.
540e5e4ff974df52aa870085904b6670c4d22ada0acDan Gohman  // For now, just do a manual check to prevent silent misencoding.
541e5e4ff974df52aa870085904b6670c4d22ada0acDan Gohman  if (Is64Bit) {
542e5e4ff974df52aa870085904b6670c4d22ada0acDan Gohman    if (Name == "popfl")
543e5e4ff974df52aa870085904b6670c4d22ada0acDan Gohman      return Error(NameLoc, "popfl cannot be encoded in 64-bit mode");
544e5e4ff974df52aa870085904b6670c4d22ada0acDan Gohman    else if (Name == "pushfl")
545e5e4ff974df52aa870085904b6670c4d22ada0acDan Gohman      return Error(NameLoc, "pushfl cannot be encoded in 64-bit mode");
546e5e4ff974df52aa870085904b6670c4d22ada0acDan Gohman  } else {
547e5e4ff974df52aa870085904b6670c4d22ada0acDan Gohman    if (Name == "popfq")
548e5e4ff974df52aa870085904b6670c4d22ada0acDan Gohman      return Error(NameLoc, "popfq cannot be encoded in 32-bit mode");
549e5e4ff974df52aa870085904b6670c4d22ada0acDan Gohman    else if (Name == "pushfq")
550e5e4ff974df52aa870085904b6670c4d22ada0acDan Gohman      return Error(NameLoc, "pushfq cannot be encoded in 32-bit mode");
551e5e4ff974df52aa870085904b6670c4d22ada0acDan Gohman  }
552e5e4ff974df52aa870085904b6670c4d22ada0acDan Gohman
5531b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar  // FIXME: Hack to recognize "sal..." and "rep..." for now. We need a way to
5541b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar  // represent alternative syntaxes in the .td file, without requiring
5551b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar  // instruction duplication.
5561b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar  StringRef PatchedName = StringSwitch<StringRef>(Name)
5571b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar    .Case("sal", "shl")
5581b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar    .Case("salb", "shlb")
5591b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar    .Case("sall", "shll")
5601b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar    .Case("salq", "shlq")
5611b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar    .Case("salw", "shlw")
5621b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar    .Case("repe", "rep")
5631b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar    .Case("repz", "rep")
5641b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar    .Case("repnz", "repne")
565e5e4ff974df52aa870085904b6670c4d22ada0acDan Gohman    .Case("pushf", Is64Bit ? "pushfq" : "pushfl")
566e5e4ff974df52aa870085904b6670c4d22ada0acDan Gohman    .Case("popf",  Is64Bit ? "popfq"  : "popfl")
5671b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar    .Default(Name);
5681b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar  Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
56916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
57016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5710db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar
5720db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar    // Parse '*' modifier.
5730db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar    if (getLexer().is(AsmToken::Star)) {
57418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan      SMLoc Loc = Parser.getTok().getLoc();
575b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner      Operands.push_back(X86Operand::CreateToken("*", Loc));
576b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex(); // Eat the star.
5770db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar    }
5780db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar
57916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // Read the first operand.
580309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner    if (X86Operand *Op = ParseOperand())
581309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner      Operands.push_back(Op);
582309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner    else
58316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      return true;
584309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner
58516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    while (getLexer().is(AsmToken::Comma)) {
586b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();  // Eat the comma.
58716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
58816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // Parse and remember the operand.
589309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner      if (X86Operand *Op = ParseOperand())
590309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        Operands.push_back(Op);
591309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner      else
59216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar        return true;
59316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    }
59416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
59516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
596d5e7705a05947e60806b795880f09757e835f590Daniel Dunbar  // FIXME: Hack to handle recognizing s{hr,ar,hl}? $1.
597d5e7705a05947e60806b795880f09757e835f590Daniel Dunbar  if ((Name.startswith("shr") || Name.startswith("sar") ||
598d5e7705a05947e60806b795880f09757e835f590Daniel Dunbar       Name.startswith("shl")) &&
599d5e7705a05947e60806b795880f09757e835f590Daniel Dunbar      Operands.size() == 3 &&
600d5e7705a05947e60806b795880f09757e835f590Daniel Dunbar      static_cast<X86Operand*>(Operands[1])->isImm() &&
601d5e7705a05947e60806b795880f09757e835f590Daniel Dunbar      isa<MCConstantExpr>(static_cast<X86Operand*>(Operands[1])->getImm()) &&
602f2de13f8d7bed958538bbd9dbeb9b15ea48456ccDaniel Dunbar      cast<MCConstantExpr>(static_cast<X86Operand*>(Operands[1])->getImm())->getValue() == 1) {
603f2de13f8d7bed958538bbd9dbeb9b15ea48456ccDaniel Dunbar    delete Operands[1];
604d5e7705a05947e60806b795880f09757e835f590Daniel Dunbar    Operands.erase(Operands.begin() + 1);
605f2de13f8d7bed958538bbd9dbeb9b15ea48456ccDaniel Dunbar  }
606d5e7705a05947e60806b795880f09757e835f590Daniel Dunbar
6079898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner  return false;
608a3af370dc12f6d5100da5d614ab0a62da135569aDaniel Dunbar}
609a3af370dc12f6d5100da5d614ab0a62da135569aDaniel Dunbar
6109c656450d65034c4cd3597fff61ef17376cff090Kevin Enderbybool X86ATTAsmParser::ParseDirective(AsmToken DirectiveID) {
6119c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby  StringRef IDVal = DirectiveID.getIdentifier();
6129c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby  if (IDVal == ".word")
6139c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby    return ParseDirectiveWord(2, DirectiveID.getLoc());
6149c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby  return true;
6159c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby}
6169c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby
6179c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby/// ParseDirectiveWord
6189c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby///  ::= .word [ expression (, expression)* ]
6199c656450d65034c4cd3597fff61ef17376cff090Kevin Enderbybool X86ATTAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
6209c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement)) {
6219c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby    for (;;) {
6229c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby      const MCExpr *Value;
6239c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby      if (getParser().ParseExpression(Value))
6249c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby        return true;
6259c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby
626aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner      getParser().getStreamer().EmitValue(Value, Size, 0 /*addrspace*/);
6279c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby
6289c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby      if (getLexer().is(AsmToken::EndOfStatement))
6299c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby        break;
6309c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby
6319c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby      // FIXME: Improve diagnostic.
6329c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby      if (getLexer().isNot(AsmToken::Comma))
6339c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby        return Error(L, "unexpected token in directive");
634b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();
6359c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby    }
6369c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby  }
6379c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby
638b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
6399c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby  return false;
6409c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby}
6419c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby
642b5505d0ee34c22ca25189e035e29e07323311ec9Chris Lattner/// LowerMOffset - Lower an 'moffset' form of an instruction, which just has a
643b5505d0ee34c22ca25189e035e29e07323311ec9Chris Lattner/// imm operand, to having "rm" or "mr" operands with the offset in the disp
644b5505d0ee34c22ca25189e035e29e07323311ec9Chris Lattner/// field.
645b5505d0ee34c22ca25189e035e29e07323311ec9Chris Lattnerstatic void LowerMOffset(MCInst &Inst, unsigned Opc, unsigned RegNo,
646b5505d0ee34c22ca25189e035e29e07323311ec9Chris Lattner                         bool isMR) {
647b5505d0ee34c22ca25189e035e29e07323311ec9Chris Lattner  MCOperand Disp = Inst.getOperand(0);
648b5505d0ee34c22ca25189e035e29e07323311ec9Chris Lattner
649b5505d0ee34c22ca25189e035e29e07323311ec9Chris Lattner  // Start over with an empty instruction.
650b5505d0ee34c22ca25189e035e29e07323311ec9Chris Lattner  Inst = MCInst();
651b5505d0ee34c22ca25189e035e29e07323311ec9Chris Lattner  Inst.setOpcode(Opc);
652b5505d0ee34c22ca25189e035e29e07323311ec9Chris Lattner
653b5505d0ee34c22ca25189e035e29e07323311ec9Chris Lattner  if (!isMR)
654b5505d0ee34c22ca25189e035e29e07323311ec9Chris Lattner    Inst.addOperand(MCOperand::CreateReg(RegNo));
655b5505d0ee34c22ca25189e035e29e07323311ec9Chris Lattner
656b5505d0ee34c22ca25189e035e29e07323311ec9Chris Lattner  // Add the mem operand.
657b5505d0ee34c22ca25189e035e29e07323311ec9Chris Lattner  Inst.addOperand(MCOperand::CreateReg(0));  // Segment
658b5505d0ee34c22ca25189e035e29e07323311ec9Chris Lattner  Inst.addOperand(MCOperand::CreateImm(1));  // Scale
659b5505d0ee34c22ca25189e035e29e07323311ec9Chris Lattner  Inst.addOperand(MCOperand::CreateReg(0));  // IndexReg
660b5505d0ee34c22ca25189e035e29e07323311ec9Chris Lattner  Inst.addOperand(Disp);                     // Displacement
661b5505d0ee34c22ca25189e035e29e07323311ec9Chris Lattner  Inst.addOperand(MCOperand::CreateReg(0));  // BaseReg
662b5505d0ee34c22ca25189e035e29e07323311ec9Chris Lattner
663b5505d0ee34c22ca25189e035e29e07323311ec9Chris Lattner  if (isMR)
664b5505d0ee34c22ca25189e035e29e07323311ec9Chris Lattner    Inst.addOperand(MCOperand::CreateReg(RegNo));
665b5505d0ee34c22ca25189e035e29e07323311ec9Chris Lattner}
666b5505d0ee34c22ca25189e035e29e07323311ec9Chris Lattner
667f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar// FIXME: Custom X86 cleanup function to implement a temporary hack to handle
668f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar// matching INCL/DECL correctly for x86_64. This needs to be replaced by a
669f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar// proper mechanism for supporting (ambiguous) feature dependent instructions.
670f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbarvoid X86ATTAsmParser::InstructionCleanup(MCInst &Inst) {
671f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar  if (!Is64Bit) return;
672f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar
673f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar  switch (Inst.getOpcode()) {
674f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar  case X86::DEC16r: Inst.setOpcode(X86::DEC64_16r); break;
675f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar  case X86::DEC16m: Inst.setOpcode(X86::DEC64_16m); break;
676f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar  case X86::DEC32r: Inst.setOpcode(X86::DEC64_32r); break;
677f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar  case X86::DEC32m: Inst.setOpcode(X86::DEC64_32m); break;
678f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar  case X86::INC16r: Inst.setOpcode(X86::INC64_16r); break;
679f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar  case X86::INC16m: Inst.setOpcode(X86::INC64_16m); break;
680f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar  case X86::INC32r: Inst.setOpcode(X86::INC64_32r); break;
681f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar  case X86::INC32m: Inst.setOpcode(X86::INC64_32m); break;
682b5505d0ee34c22ca25189e035e29e07323311ec9Chris Lattner
683b5505d0ee34c22ca25189e035e29e07323311ec9Chris Lattner  // moffset instructions are x86-32 only.
684b5505d0ee34c22ca25189e035e29e07323311ec9Chris Lattner  case X86::MOV8o8a:   LowerMOffset(Inst, X86::MOV8rm , X86::AL , false); break;
685b5505d0ee34c22ca25189e035e29e07323311ec9Chris Lattner  case X86::MOV16o16a: LowerMOffset(Inst, X86::MOV16rm, X86::AX , false); break;
686b5505d0ee34c22ca25189e035e29e07323311ec9Chris Lattner  case X86::MOV32o32a: LowerMOffset(Inst, X86::MOV32rm, X86::EAX, false); break;
687b5505d0ee34c22ca25189e035e29e07323311ec9Chris Lattner  case X86::MOV8ao8:   LowerMOffset(Inst, X86::MOV8mr , X86::AL , true); break;
688b5505d0ee34c22ca25189e035e29e07323311ec9Chris Lattner  case X86::MOV16ao16: LowerMOffset(Inst, X86::MOV16mr, X86::AX , true); break;
689b5505d0ee34c22ca25189e035e29e07323311ec9Chris Lattner  case X86::MOV32ao32: LowerMOffset(Inst, X86::MOV32mr, X86::EAX, true); break;
690f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar  }
691f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar}
692f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar
693c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbarbool
694c918d6043b823173b106c163038b14c1e2f92765Daniel DunbarX86ATTAsmParser::MatchInstruction(const SmallVectorImpl<MCParsedAsmOperand*>
695c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar                                    &Operands,
696c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar                                  MCInst &Inst) {
697c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // First, try a direct match.
698c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  if (!MatchInstructionImpl(Operands, Inst))
699c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar    return false;
700c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
701c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // Ignore anything which is obviously not a suffix match.
702c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  if (Operands.size() == 0)
703c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar    return true;
704c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  X86Operand *Op = static_cast<X86Operand*>(Operands[0]);
705c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  if (!Op->isToken() || Op->getToken().size() > 15)
706c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar    return true;
707c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
708c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // FIXME: Ideally, we would only attempt suffix matches for things which are
709c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // valid prefixes, and we could just infer the right unambiguous
710c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // type. However, that requires substantially more matcher support than the
711c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // following hack.
712c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
713c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // Change the operand to point to a temporary token.
714c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  char Tmp[16];
715c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  StringRef Base = Op->getToken();
716c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  memcpy(Tmp, Base.data(), Base.size());
717c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  Op->setTokenValue(StringRef(Tmp, Base.size() + 1));
718c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
719c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // Check for the various suffix matches.
720c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  Tmp[Base.size()] = 'b';
721c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  bool MatchB = MatchInstructionImpl(Operands, Inst);
722c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  Tmp[Base.size()] = 'w';
723c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  bool MatchW = MatchInstructionImpl(Operands, Inst);
724c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  Tmp[Base.size()] = 'l';
725c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  bool MatchL = MatchInstructionImpl(Operands, Inst);
7260481449a0536311b5fefc9122ce679000540e013Daniel Dunbar  Tmp[Base.size()] = 'q';
7270481449a0536311b5fefc9122ce679000540e013Daniel Dunbar  bool MatchQ = MatchInstructionImpl(Operands, Inst);
728c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
729c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // Restore the old token.
730c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  Op->setTokenValue(Base);
731c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
732c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // If exactly one matched, then we treat that as a successful match (and the
733c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // instruction will already have been filled in correctly, since the failing
734c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // matches won't have modified it).
7350481449a0536311b5fefc9122ce679000540e013Daniel Dunbar  if (MatchB + MatchW + MatchL + MatchQ == 3)
736c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar    return false;
737c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
738c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // Otherwise, the match failed.
739c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  return true;
740c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar}
741c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
742c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
743e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callananextern "C" void LLVMInitializeX86AsmLexer();
744e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan
745092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar// Force static initialization.
746092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbarextern "C" void LLVMInitializeX86AsmParser() {
747f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar  RegisterAsmParser<X86_32ATTAsmParser> X(TheX86_32Target);
748f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar  RegisterAsmParser<X86_64ATTAsmParser> Y(TheX86_64Target);
749e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan  LLVMInitializeX86AsmLexer();
750092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar}
7510e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar
7520e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar#include "X86GenAsmMatcher.inc"
753