X86AsmParser.cpp revision b80d571ea85db5d52fafed0523cf59e693502198
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;
3716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbarprivate:
3816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  MCAsmParser &getParser() const { return Parser; }
39a2edbabcb86f213eca6daeda5d801f8c7b1e44b2Daniel Dunbar
4016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
4116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
42d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner  bool Error(SMLoc L, const Twine &Msg,
43d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner             ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()) {
44d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner    return Parser.Error(L, Msg, Ranges);
45d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner  }
4616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
47d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  X86Operand *ErrorOperand(SMLoc Loc, StringRef Msg) {
48d37ad247cc04c2a436e537767ac1aec709901594Devang Patel    Error(Loc, Msg);
49d37ad247cc04c2a436e537767ac1aec709901594Devang Patel    return 0;
50d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  }
51d37ad247cc04c2a436e537767ac1aec709901594Devang Patel
52309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner  X86Operand *ParseOperand();
530a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  X86Operand *ParseATTOperand();
540a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  X86Operand *ParseIntelOperand();
55d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  X86Operand *ParseIntelMemOperand();
567c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel  X86Operand *ParseIntelBracExpression(unsigned SegReg, unsigned Size);
57eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner  X86Operand *ParseMemOperand(unsigned SegReg, SMLoc StartLoc);
589c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby
599c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby  bool ParseDirectiveWord(unsigned Size, SMLoc L);
60bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng  bool ParseDirectiveCode(StringRef IDVal, SMLoc L);
619c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby
62b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel  bool processInstruction(MCInst &Inst,
63b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel                          const SmallVectorImpl<MCParsedAsmOperand*> &Ops);
64b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel
657036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner  bool MatchAndEmitInstruction(SMLoc IDLoc,
667c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner                               SmallVectorImpl<MCParsedAsmOperand*> &Operands,
677036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner                               MCStreamer &Out);
6820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
6996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  /// isSrcOp - Returns true if operand is either (%rsi) or %ds:%(rsi)
7096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  /// in 64bit mode or (%edi) or %es:(%edi) in 32bit mode.
7196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  bool isSrcOp(X86Operand &Op);
7296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger
7396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  /// isDstOp - Returns true if operand is either %es:(%rdi) in 64bit mode
7496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  /// or %es:(%edi) in 32bit mode.
7596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  bool isDstOp(X86Operand &Op);
7696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger
7759ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  bool is64BitMode() const {
78ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    // FIXME: Can tablegen auto-generate this?
79ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    return (STI.getFeatureBits() & X86::Mode64Bit) != 0;
80ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
81bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng  void SwitchMode() {
82bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(X86::Mode64Bit));
83bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    setAvailableFeatures(FB);
84bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng  }
85ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
8654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  /// @name Auto-generated Matcher Functions
8754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  /// {
88c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
890692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER
900692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "X86GenAsmMatcher.inc"
91c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
920e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar  /// }
9316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
9416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbarpublic:
95dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patel  X86AsmParser(MCSubtargetInfo &sti, MCAsmParser &parser)
960db58bfecea020ffcdfa1fc6458995371e1c3c50Devang Patel    : MCTargetAsmParser(), STI(sti), Parser(parser) {
97c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
9854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar    // Initialize the set of available features.
99ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
10054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  }
101bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky  virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
10216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
10338e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc,
1049898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner                                SmallVectorImpl<MCParsedAsmOperand*> &Operands);
1059c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby
1069c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby  virtual bool ParseDirective(AsmToken DirectiveID);
107be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel
108be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel  bool isParsingIntelSyntax() {
1090db58bfecea020ffcdfa1fc6458995371e1c3c50Devang Patel    return getParser().getAssemblerDialect();
110be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel  }
11116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar};
11237dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner} // end anonymous namespace
11337dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner
114e9b466d4f09de3b46c0d0d1e71cabddc7cc9021bSean Callanan/// @name Auto-generated Match Functions
115f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes/// {
116e9b466d4f09de3b46c0d0d1e71cabddc7cc9021bSean Callanan
117b8d6e98e566724f58344d275a4bd675249bb713aChris Lattnerstatic unsigned MatchRegisterName(StringRef Name);
118e9b466d4f09de3b46c0d0d1e71cabddc7cc9021bSean Callanan
119e9b466d4f09de3b46c0d0d1e71cabddc7cc9021bSean Callanan/// }
12037dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner
121b8ba13f0096b560ee618512019ca86969a9fa772Devang Patelstatic  bool isImmSExti16i8Value(uint64_t Value) {
122b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel  return ((                                  Value <= 0x000000000000007FULL)||
123b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel          (0x000000000000FF80ULL <= Value && Value <= 0x000000000000FFFFULL)||
124b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel          (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
125b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel}
126b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel
127b8ba13f0096b560ee618512019ca86969a9fa772Devang Patelstatic bool isImmSExti32i8Value(uint64_t Value) {
128b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel  return ((                                  Value <= 0x000000000000007FULL)||
129b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel          (0x00000000FFFFFF80ULL <= Value && Value <= 0x00000000FFFFFFFFULL)||
130b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel          (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
131b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel}
132b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel
133b8ba13f0096b560ee618512019ca86969a9fa772Devang Patelstatic bool isImmZExtu32u8Value(uint64_t Value) {
134b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    return (Value <= 0x00000000000000FFULL);
135b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel}
136b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel
137b8ba13f0096b560ee618512019ca86969a9fa772Devang Patelstatic bool isImmSExti64i8Value(uint64_t Value) {
138b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel  return ((                                  Value <= 0x000000000000007FULL)||
139b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel	  (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
140b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel}
141b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel
142b8ba13f0096b560ee618512019ca86969a9fa772Devang Patelstatic bool isImmSExti64i32Value(uint64_t Value) {
143b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel  return ((                                  Value <= 0x000000007FFFFFFFULL)||
144b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel	  (0xFFFFFFFF80000000ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
145b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel}
14637dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattnernamespace {
14716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
14816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar/// X86Operand - Instances of this class represent a parsed X86 machine
14916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar/// instruction.
15045220a84394758c86cc29ee0e3fe6738946fbcd0Chris Lattnerstruct X86Operand : public MCParsedAsmOperand {
1511f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner  enum KindTy {
15220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    Token,
15316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    Register,
15416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    Immediate,
15516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    Memory
15616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  } Kind;
15716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
15829ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner  SMLoc StartLoc, EndLoc;
159f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
16016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  union {
16116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    struct {
16220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar      const char *Data;
16320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar      unsigned Length;
16420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    } Tok;
16520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
16620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    struct {
16716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      unsigned RegNo;
16816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    } Reg;
16916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
17016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    struct {
1718c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar      const MCExpr *Val;
17216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    } Imm;
17316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
17416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    struct {
17516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      unsigned SegReg;
1768c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar      const MCExpr *Disp;
17716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      unsigned BaseReg;
17816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      unsigned IndexReg;
17916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      unsigned Scale;
180c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel      unsigned Size;
18116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    } Mem;
182dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar  };
18316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
1840a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner  X86Operand(KindTy K, SMLoc Start, SMLoc End)
1851f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner    : Kind(K), StartLoc(Start), EndLoc(End) {}
186c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
1871f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner  /// getStartLoc - Get the location of the first token of this operand.
1881f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner  SMLoc getStartLoc() const { return StartLoc; }
1891f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner  /// getEndLoc - Get the location of the last token of this operand.
1901f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner  SMLoc getEndLoc() const { return EndLoc; }
191d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner
192d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner  SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
1931f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner
194b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbach  virtual void print(raw_ostream &OS) const {}
195b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar
19620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  StringRef getToken() const {
19720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    assert(Kind == Token && "Invalid access!");
19820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    return StringRef(Tok.Data, Tok.Length);
19920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  }
200c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  void setTokenValue(StringRef Value) {
201c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar    assert(Kind == Token && "Invalid access!");
202c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar    Tok.Data = Value.data();
203c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar    Tok.Length = Value.size();
204c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  }
20520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
20616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  unsigned getReg() const {
20716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    assert(Kind == Register && "Invalid access!");
20816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    return Reg.RegNo;
20916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
21016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
2118c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar  const MCExpr *getImm() const {
212022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Immediate && "Invalid access!");
213022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Imm.Val;
214022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
215022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar
2168c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar  const MCExpr *getMemDisp() const {
217022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Memory && "Invalid access!");
218022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Mem.Disp;
219022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
220022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  unsigned getMemSegReg() const {
221022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Memory && "Invalid access!");
222022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Mem.SegReg;
223022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
224022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  unsigned getMemBaseReg() const {
225022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Memory && "Invalid access!");
226022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Mem.BaseReg;
227022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
228022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  unsigned getMemIndexReg() const {
229022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Memory && "Invalid access!");
230022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Mem.IndexReg;
231022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
232022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  unsigned getMemScale() const {
233022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Memory && "Invalid access!");
234022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Mem.Scale;
235022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
236022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar
237a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  bool isToken() const {return Kind == Token; }
23820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
23920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  bool isImm() const { return Kind == Immediate; }
240f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
24162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar  bool isImmSExti16i8() const {
2425fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar    if (!isImm())
2435fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar      return false;
2445fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar
24562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // If this isn't a constant expr, just assume it fits and let relaxation
24662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // handle it.
24762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
24862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    if (!CE)
24962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar      return true;
25062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar
25162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // Otherwise, check the value is in a range that makes sense for this
25262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // extension.
253b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    return isImmSExti16i8Value(CE->getValue());
25462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar  }
25562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar  bool isImmSExti32i8() const {
25662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    if (!isImm())
25762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar      return false;
2585fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar
25962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // If this isn't a constant expr, just assume it fits and let relaxation
26062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // handle it.
26162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
26262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    if (!CE)
26362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar      return true;
26462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar
26562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // Otherwise, check the value is in a range that makes sense for this
26662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // extension.
267b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    return isImmSExti32i8Value(CE->getValue());
2685fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar  }
269c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby  bool isImmZExtu32u8() const {
270c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby    if (!isImm())
271c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby      return false;
272c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby
273c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby    // If this isn't a constant expr, just assume it fits and let relaxation
274c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby    // handle it.
275c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
276c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby    if (!CE)
277c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby      return true;
278c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby
279c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby    // Otherwise, check the value is in a range that makes sense for this
280c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby    // extension.
281b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    return isImmZExtu32u8Value(CE->getValue());
282c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby  }
28362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar  bool isImmSExti64i8() const {
2841fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar    if (!isImm())
2851fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar      return false;
2861fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar
28762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // If this isn't a constant expr, just assume it fits and let relaxation
28862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // handle it.
28962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
29062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    if (!CE)
29162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar      return true;
29262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar
29362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // Otherwise, check the value is in a range that makes sense for this
29462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // extension.
295b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    return isImmSExti64i8Value(CE->getValue());
29662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar  }
29762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar  bool isImmSExti64i32() const {
29862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    if (!isImm())
29962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar      return false;
3001fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar
30162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // If this isn't a constant expr, just assume it fits and let relaxation
30262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // handle it.
30362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
30462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    if (!CE)
30562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar      return true;
30662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar
30762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // Otherwise, check the value is in a range that makes sense for this
30862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // extension.
309b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    return isImmSExti64i32Value(CE->getValue());
3101fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar  }
3111fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar
31220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  bool isMem() const { return Kind == Memory; }
313c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  bool isMem8() const {
314c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel    return Kind == Memory && (!Mem.Size || Mem.Size == 8);
315c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
316c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  bool isMem16() const {
317c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel    return Kind == Memory && (!Mem.Size || Mem.Size == 16);
318c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
319c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  bool isMem32() const {
320c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel    return Kind == Memory && (!Mem.Size || Mem.Size == 32);
321c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
322c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  bool isMem64() const {
323c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel    return Kind == Memory && (!Mem.Size || Mem.Size == 64);
324c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
325c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  bool isMem80() const {
326c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel    return Kind == Memory && (!Mem.Size || Mem.Size == 80);
327c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
328c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  bool isMem128() const {
329c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel    return Kind == Memory && (!Mem.Size || Mem.Size == 128);
330c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
331c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  bool isMem256() const {
332c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel    return Kind == Memory && (!Mem.Size || Mem.Size == 256);
333c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
33420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
335b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  bool isAbsMem() const {
336b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
3377b9147afa7d1875353e1c1347b6b6cf71f548229Daniel Dunbar      !getMemIndexReg() && getMemScale() == 1;
338b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  }
339b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar
34020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  bool isReg() const { return Kind == Register; }
34120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
3429c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
3439c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar    // Add as immediates when possible.
3449c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
3459c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
3469c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar    else
3479c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar      Inst.addOperand(MCOperand::CreateExpr(Expr));
3489c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar  }
3499c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar
3505c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar  void addRegOperands(MCInst &Inst, unsigned N) const {
35120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    assert(N == 1 && "Invalid number of operands!");
35220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getReg()));
35320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  }
35420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
3555c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar  void addImmOperands(MCInst &Inst, unsigned N) const {
35620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    assert(N == 1 && "Invalid number of operands!");
3579c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar    addExpr(Inst, getImm());
35820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  }
35920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
360c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  void addMem8Operands(MCInst &Inst, unsigned N) const {
361c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel    addMemOperands(Inst, N);
362c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
363c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  void addMem16Operands(MCInst &Inst, unsigned N) const {
364c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel    addMemOperands(Inst, N);
365c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
366c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  void addMem32Operands(MCInst &Inst, unsigned N) const {
367c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel    addMemOperands(Inst, N);
368c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
369c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  void addMem64Operands(MCInst &Inst, unsigned N) const {
370c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel    addMemOperands(Inst, N);
371c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
372c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  void addMem80Operands(MCInst &Inst, unsigned N) const {
373c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel    addMemOperands(Inst, N);
374c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
375c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  void addMem128Operands(MCInst &Inst, unsigned N) const {
376c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel    addMemOperands(Inst, N);
377c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
378c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  void addMem256Operands(MCInst &Inst, unsigned N) const {
379c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel    addMemOperands(Inst, N);
380c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
381c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel
3825c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar  void addMemOperands(MCInst &Inst, unsigned N) const {
383ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar    assert((N == 5) && "Invalid number of operands!");
38420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
38520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    Inst.addOperand(MCOperand::CreateImm(getMemScale()));
38620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemIndexReg()));
3879c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar    addExpr(Inst, getMemDisp());
388ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
389ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar  }
390ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar
391b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  void addAbsMemOperands(MCInst &Inst, unsigned N) const {
392b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    assert((N == 1) && "Invalid number of operands!");
393b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby    // Add as immediates when possible.
394b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
395b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
396b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby    else
397b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby      Inst.addOperand(MCOperand::CreateExpr(getMemDisp()));
398b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  }
399b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar
400b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner  static X86Operand *CreateToken(StringRef Str, SMLoc Loc) {
401f82edaffb1a6d41bc89d86c69f53962e63621aadBenjamin Kramer    SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size() - 1);
402f82edaffb1a6d41bc89d86c69f53962e63621aadBenjamin Kramer    X86Operand *Res = new X86Operand(Token, Loc, EndLoc);
40329ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Tok.Data = Str.data();
40429ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Tok.Length = Str.size();
40520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    return Res;
40620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  }
40720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
40829ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner  static X86Operand *CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc) {
4091f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner    X86Operand *Res = new X86Operand(Register, StartLoc, EndLoc);
41029ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Reg.RegNo = RegNo;
41129ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    return Res;
41216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
41320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
414b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner  static X86Operand *CreateImm(const MCExpr *Val, SMLoc StartLoc, SMLoc EndLoc){
415b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner    X86Operand *Res = new X86Operand(Immediate, StartLoc, EndLoc);
41629ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Imm.Val = Val;
41729ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    return Res;
41816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
41920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
420b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  /// Create an absolute memory operand.
421b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  static X86Operand *CreateMem(const MCExpr *Disp, SMLoc StartLoc,
422c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel                               SMLoc EndLoc, unsigned Size = 0) {
423b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc);
424b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    Res->Mem.SegReg   = 0;
425b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    Res->Mem.Disp     = Disp;
426b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    Res->Mem.BaseReg  = 0;
427b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    Res->Mem.IndexReg = 0;
4287b9147afa7d1875353e1c1347b6b6cf71f548229Daniel Dunbar    Res->Mem.Scale    = 1;
429c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel    Res->Mem.Size     = Size;
430b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    return Res;
431b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  }
432b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar
433b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  /// Create a generalized memory operand.
434309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner  static X86Operand *CreateMem(unsigned SegReg, const MCExpr *Disp,
435309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner                               unsigned BaseReg, unsigned IndexReg,
436c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel                               unsigned Scale, SMLoc StartLoc, SMLoc EndLoc,
437c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel                               unsigned Size = 0) {
438b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    // We should never just have a displacement, that should be parsed as an
439b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    // absolute memory operand.
440c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar    assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
441c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar
442022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    // The scale should always be one of {1,2,4,8}.
443022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
44416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar           "Invalid scale!");
4450a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner    X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc);
44629ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Mem.SegReg   = SegReg;
44729ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Mem.Disp     = Disp;
44829ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Mem.BaseReg  = BaseReg;
44929ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Mem.IndexReg = IndexReg;
45029ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Mem.Scale    = Scale;
451c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel    Res->Mem.Size     = Size;
45229ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    return Res;
45316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
45416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar};
45516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
45637dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner} // end anonymous namespace.
45716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
458dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patelbool X86AsmParser::isSrcOp(X86Operand &Op) {
45959ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  unsigned basereg = is64BitMode() ? X86::RSI : X86::ESI;
46096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger
46196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  return (Op.isMem() &&
46296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    (Op.Mem.SegReg == 0 || Op.Mem.SegReg == X86::DS) &&
46396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    isa<MCConstantExpr>(Op.Mem.Disp) &&
46496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
46596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    Op.Mem.BaseReg == basereg && Op.Mem.IndexReg == 0);
46696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger}
46796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger
468dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patelbool X86AsmParser::isDstOp(X86Operand &Op) {
46959ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  unsigned basereg = is64BitMode() ? X86::RDI : X86::EDI;
47096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger
47196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  return Op.isMem() && Op.Mem.SegReg == X86::ES &&
47296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    isa<MCConstantExpr>(Op.Mem.Disp) &&
47396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
47496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    Op.Mem.BaseReg == basereg && Op.Mem.IndexReg == 0;
47596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger}
47616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
477dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patelbool X86AsmParser::ParseRegister(unsigned &RegNo,
478dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patel                                 SMLoc &StartLoc, SMLoc &EndLoc) {
47923075746a1418f281bc2a088ea85560bfd833599Chris Lattner  RegNo = 0;
480be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel  if (!isParsingIntelSyntax()) {
4811aea430b8834f7bed3a14eda5027eac2133d6496Devang Patel    const AsmToken &TokPercent = Parser.getTok();
482d37ad247cc04c2a436e537767ac1aec709901594Devang Patel    assert(TokPercent.is(AsmToken::Percent) && "Invalid token kind!");
483d37ad247cc04c2a436e537767ac1aec709901594Devang Patel    StartLoc = TokPercent.getLoc();
484d37ad247cc04c2a436e537767ac1aec709901594Devang Patel    Parser.Lex(); // Eat percent token.
485d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  }
4867b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby
48718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
4881aea430b8834f7bed3a14eda5027eac2133d6496Devang Patel  if (Tok.isNot(AsmToken::Identifier)) {
489be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel    if (isParsingIntelSyntax()) return true;
4905efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer    return Error(StartLoc, "invalid register name",
4915efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer                 SMRange(StartLoc, Tok.getEndLoc()));
4921aea430b8834f7bed3a14eda5027eac2133d6496Devang Patel  }
49316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
4947b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby  RegNo = MatchRegisterName(Tok.getString());
495f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
49633d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner  // If the match failed, try the register name as lowercase.
49733d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner  if (RegNo == 0)
498590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer    RegNo = MatchRegisterName(Tok.getString().lower());
499c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
5005de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng  if (!is64BitMode()) {
5015de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng    // FIXME: This should be done using Requires<In32BitMode> and
5025de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng    // Requires<In64BitMode> so "eiz" usage in 64-bit instructions can be also
5035de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng    // checked.
5045de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng    // FIXME: Check AH, CH, DH, BH cannot be used in an instruction requiring a
5055de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng    // REX prefix.
5065de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng    if (RegNo == X86::RIZ ||
5075de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng        X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo) ||
5085de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng        X86II::isX86_64NonExtLowByteReg(RegNo) ||
5095de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng        X86II::isX86_64ExtendedReg(RegNo))
5105efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer      return Error(StartLoc, "register %"
5115efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer                   + Tok.getString() + " is only available in 64-bit mode",
5125efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer                   SMRange(StartLoc, Tok.getEndLoc()));
5135de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng  }
5143c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes
51533d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner  // Parse "%st" as "%st(0)" and "%st(1)", which is multiple tokens.
51633d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner  if (RegNo == 0 && (Tok.getString() == "st" || Tok.getString() == "ST")) {
517e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    RegNo = X86::ST0;
518e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    EndLoc = Tok.getLoc();
519e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    Parser.Lex(); // Eat 'st'
520f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
521e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    // Check to see if we have '(4)' after %st.
522e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    if (getLexer().isNot(AsmToken::LParen))
523e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner      return false;
524e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    // Lex the paren.
525e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    getParser().Lex();
526e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner
527e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    const AsmToken &IntTok = Parser.getTok();
528e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    if (IntTok.isNot(AsmToken::Integer))
529e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner      return Error(IntTok.getLoc(), "expected stack index");
530e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    switch (IntTok.getIntVal()) {
531e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 0: RegNo = X86::ST0; break;
532e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 1: RegNo = X86::ST1; break;
533e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 2: RegNo = X86::ST2; break;
534e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 3: RegNo = X86::ST3; break;
535e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 4: RegNo = X86::ST4; break;
536e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 5: RegNo = X86::ST5; break;
537e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 6: RegNo = X86::ST6; break;
538e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 7: RegNo = X86::ST7; break;
539e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    default: return Error(IntTok.getLoc(), "invalid stack index");
540e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    }
541f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
542e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    if (getParser().Lex().isNot(AsmToken::RParen))
543e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner      return Error(Parser.getTok().getLoc(), "expected ')'");
544f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
545e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    EndLoc = Tok.getLoc();
546e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    Parser.Lex(); // Eat ')'
547e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    return false;
548e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner  }
549f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
550645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner  // If this is "db[0-7]", match it as an alias
551645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner  // for dr[0-7].
552645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner  if (RegNo == 0 && Tok.getString().size() == 3 &&
553645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner      Tok.getString().startswith("db")) {
554645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    switch (Tok.getString()[2]) {
555645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '0': RegNo = X86::DR0; break;
556645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '1': RegNo = X86::DR1; break;
557645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '2': RegNo = X86::DR2; break;
558645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '3': RegNo = X86::DR3; break;
559645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '4': RegNo = X86::DR4; break;
560645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '5': RegNo = X86::DR5; break;
561645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '6': RegNo = X86::DR6; break;
562645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '7': RegNo = X86::DR7; break;
563645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    }
564f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
565645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    if (RegNo != 0) {
566645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner      EndLoc = Tok.getLoc();
567645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner      Parser.Lex(); // Eat it.
568645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner      return false;
569645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    }
570645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner  }
571f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
5721aea430b8834f7bed3a14eda5027eac2133d6496Devang Patel  if (RegNo == 0) {
573be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel    if (isParsingIntelSyntax()) return true;
5745efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer    return Error(StartLoc, "invalid register name",
5755efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer                 SMRange(StartLoc, Tok.getEndLoc()));
5761aea430b8834f7bed3a14eda5027eac2133d6496Devang Patel  }
5770e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar
5785efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer  EndLoc = Tok.getEndLoc();
579b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat identifier token.
58016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  return false;
581092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar}
582092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar
583dd929fc704054fa79cc1171354f95d91a5b62de2Devang PatelX86Operand *X86AsmParser::ParseOperand() {
584be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel  if (isParsingIntelSyntax())
5850a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel    return ParseIntelOperand();
5860a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  return ParseATTOperand();
5870a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel}
5880a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel
589d37ad247cc04c2a436e537767ac1aec709901594Devang Patel/// getIntelMemOperandSize - Return intel memory operand size.
590d37ad247cc04c2a436e537767ac1aec709901594Devang Patelstatic unsigned getIntelMemOperandSize(StringRef OpStr) {
591d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  unsigned Size = 0;
5920a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  if (OpStr == "BYTE") Size = 8;
5930a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  if (OpStr == "WORD") Size = 16;
5940a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  if (OpStr == "DWORD") Size = 32;
5950a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  if (OpStr == "QWORD") Size = 64;
5960a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  if (OpStr == "XWORD") Size = 80;
5970a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  if (OpStr == "XMMWORD") Size = 128;
5980a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  if (OpStr == "YMMWORD") Size = 256;
599d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  return Size;
6000a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel}
6010a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel
6027c64fe651ad4581ac66b6407116144442a8a7f03Devang PatelX86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg,
6037c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel                                                   unsigned Size) {
6047c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel  unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
605c798cc42831150f678b080c0994c1cc024bae653Devang Patel  SMLoc Start = Parser.getTok().getLoc(), End;
606c798cc42831150f678b080c0994c1cc024bae653Devang Patel
607d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext());
608d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  // Parse [ BaseReg + Scale*IndexReg + Disp ] or [ symbol ]
6090a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel
610d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  // Eat '['
611d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  if (getLexer().isNot(AsmToken::LBrac))
612d37ad247cc04c2a436e537767ac1aec709901594Devang Patel    return ErrorOperand(Start, "Expected '[' token!");
613d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  Parser.Lex();
614d37ad247cc04c2a436e537767ac1aec709901594Devang Patel
615d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  if (getLexer().is(AsmToken::Identifier)) {
616d37ad247cc04c2a436e537767ac1aec709901594Devang Patel    // Parse BaseReg
6171aea430b8834f7bed3a14eda5027eac2133d6496Devang Patel    if (ParseRegister(BaseReg, Start, End)) {
618d37ad247cc04c2a436e537767ac1aec709901594Devang Patel      // Handle '[' 'symbol' ']'
619d37ad247cc04c2a436e537767ac1aec709901594Devang Patel      if (getParser().ParseExpression(Disp, End)) return 0;
620d37ad247cc04c2a436e537767ac1aec709901594Devang Patel      if (getLexer().isNot(AsmToken::RBrac))
621bc51e501a0cd3d2bea770d07fe39ea5e87726cb4Devang Patel        return ErrorOperand(Start, "Expected ']' token!");
62285d5aaecd03ca4bc6e406ee88c72a4ba8878bb2bDevang Patel      Parser.Lex();
623d37ad247cc04c2a436e537767ac1aec709901594Devang Patel      return X86Operand::CreateMem(Disp, Start, End, Size);
62485d5aaecd03ca4bc6e406ee88c72a4ba8878bb2bDevang Patel    }
625d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  } else if (getLexer().is(AsmToken::Integer)) {
6263e08131185d5b3245065eb027900aed56b607970Devang Patel      int64_t Val = Parser.getTok().getIntVal();
627d37ad247cc04c2a436e537767ac1aec709901594Devang Patel      Parser.Lex();
6283e08131185d5b3245065eb027900aed56b607970Devang Patel      SMLoc Loc = Parser.getTok().getLoc();
6293e08131185d5b3245065eb027900aed56b607970Devang Patel      if (getLexer().is(AsmToken::RBrac)) {
6303e08131185d5b3245065eb027900aed56b607970Devang Patel        // Handle '[' number ']'
6313e08131185d5b3245065eb027900aed56b607970Devang Patel        Parser.Lex();
632a28101e61aa3aeed5baf3d5b91d0f8bcb4e9e12aDevang Patel        const MCExpr *Disp = MCConstantExpr::Create(Val, getContext());
633a28101e61aa3aeed5baf3d5b91d0f8bcb4e9e12aDevang Patel        if (SegReg)
634a28101e61aa3aeed5baf3d5b91d0f8bcb4e9e12aDevang Patel          return X86Operand::CreateMem(SegReg, Disp, 0, 0, Scale,
635a28101e61aa3aeed5baf3d5b91d0f8bcb4e9e12aDevang Patel                                       Start, End, Size);
636a28101e61aa3aeed5baf3d5b91d0f8bcb4e9e12aDevang Patel        return X86Operand::CreateMem(Disp, Start, End, Size);
6373e08131185d5b3245065eb027900aed56b607970Devang Patel      } else if (getLexer().is(AsmToken::Star)) {
6383e08131185d5b3245065eb027900aed56b607970Devang Patel        // Handle '[' Scale*IndexReg ']'
6393e08131185d5b3245065eb027900aed56b607970Devang Patel        Parser.Lex();
6403e08131185d5b3245065eb027900aed56b607970Devang Patel        SMLoc IdxRegLoc = Parser.getTok().getLoc();
6413e08131185d5b3245065eb027900aed56b607970Devang Patel	if (ParseRegister(IndexReg, IdxRegLoc, End))
6423e08131185d5b3245065eb027900aed56b607970Devang Patel	  return ErrorOperand(IdxRegLoc, "Expected register");
6433e08131185d5b3245065eb027900aed56b607970Devang Patel        Scale = Val;
6443e08131185d5b3245065eb027900aed56b607970Devang Patel      } else
6453e08131185d5b3245065eb027900aed56b607970Devang Patel        return ErrorOperand(Loc, "Unepxeted token");
646d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  }
64785d5aaecd03ca4bc6e406ee88c72a4ba8878bb2bDevang Patel
648d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  if (getLexer().is(AsmToken::Plus) || getLexer().is(AsmToken::Minus)) {
649d37ad247cc04c2a436e537767ac1aec709901594Devang Patel    bool isPlus = getLexer().is(AsmToken::Plus);
65085d5aaecd03ca4bc6e406ee88c72a4ba8878bb2bDevang Patel    Parser.Lex();
651d37ad247cc04c2a436e537767ac1aec709901594Devang Patel    SMLoc PlusLoc = Parser.getTok().getLoc();
652d37ad247cc04c2a436e537767ac1aec709901594Devang Patel    if (getLexer().is(AsmToken::Integer)) {
653d37ad247cc04c2a436e537767ac1aec709901594Devang Patel      int64_t Val = Parser.getTok().getIntVal();
65485d5aaecd03ca4bc6e406ee88c72a4ba8878bb2bDevang Patel      Parser.Lex();
655d37ad247cc04c2a436e537767ac1aec709901594Devang Patel      if (getLexer().is(AsmToken::Star)) {
656bc51e501a0cd3d2bea770d07fe39ea5e87726cb4Devang Patel        Parser.Lex();
657bc51e501a0cd3d2bea770d07fe39ea5e87726cb4Devang Patel        SMLoc IdxRegLoc = Parser.getTok().getLoc();
6581aea430b8834f7bed3a14eda5027eac2133d6496Devang Patel	if (ParseRegister(IndexReg, IdxRegLoc, End))
6591aea430b8834f7bed3a14eda5027eac2133d6496Devang Patel	  return ErrorOperand(IdxRegLoc, "Expected register");
660bc51e501a0cd3d2bea770d07fe39ea5e87726cb4Devang Patel        Scale = Val;
661d37ad247cc04c2a436e537767ac1aec709901594Devang Patel      } else if (getLexer().is(AsmToken::RBrac)) {
662bc51e501a0cd3d2bea770d07fe39ea5e87726cb4Devang Patel        const MCExpr *ValExpr = MCConstantExpr::Create(Val, getContext());
663e60540f380cc9466f3b2f7d17adfd37db137689cDevang Patel        Disp = isPlus ? ValExpr : MCConstantExpr::Create(0-Val, getContext());
664d37ad247cc04c2a436e537767ac1aec709901594Devang Patel      } else
665bc51e501a0cd3d2bea770d07fe39ea5e87726cb4Devang Patel        return ErrorOperand(PlusLoc, "unexpected token after +");
666f2d213745e07e884c1616f2f3d0b78f9e918e5dbDevang Patel    } else if (getLexer().is(AsmToken::Identifier)) {
667392ad6d8aa5d1af7becbff4e01dd89dc44b7a00eDevang Patel      // This could be an index register or a displacement expression.
668f2d213745e07e884c1616f2f3d0b78f9e918e5dbDevang Patel      End = Parser.getTok().getLoc();
669f2d213745e07e884c1616f2f3d0b78f9e918e5dbDevang Patel      if (!IndexReg)
670f2d213745e07e884c1616f2f3d0b78f9e918e5dbDevang Patel        ParseRegister(IndexReg, Start, End);
671f2d213745e07e884c1616f2f3d0b78f9e918e5dbDevang Patel      else if (getParser().ParseExpression(Disp, End)) return 0;
672f2d213745e07e884c1616f2f3d0b78f9e918e5dbDevang Patel    }
67385d5aaecd03ca4bc6e406ee88c72a4ba8878bb2bDevang Patel  }
674c798cc42831150f678b080c0994c1cc024bae653Devang Patel
675d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  if (getLexer().isNot(AsmToken::RBrac))
676d37ad247cc04c2a436e537767ac1aec709901594Devang Patel    if (getParser().ParseExpression(Disp, End)) return 0;
677d37ad247cc04c2a436e537767ac1aec709901594Devang Patel
678d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  End = Parser.getTok().getLoc();
679d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  if (getLexer().isNot(AsmToken::RBrac))
680d37ad247cc04c2a436e537767ac1aec709901594Devang Patel    return ErrorOperand(End, "expected ']' token!");
681d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  Parser.Lex();
682d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  End = Parser.getTok().getLoc();
683fdd3b30151bc391efce74f4592a9a3bb595565a2Devang Patel
684fdd3b30151bc391efce74f4592a9a3bb595565a2Devang Patel  // handle [-42]
685fdd3b30151bc391efce74f4592a9a3bb595565a2Devang Patel  if (!BaseReg && !IndexReg)
686fdd3b30151bc391efce74f4592a9a3bb595565a2Devang Patel    return X86Operand::CreateMem(Disp, Start, End, Size);
687fdd3b30151bc391efce74f4592a9a3bb595565a2Devang Patel
688d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale,
689bc51e501a0cd3d2bea770d07fe39ea5e87726cb4Devang Patel                               Start, End, Size);
690d37ad247cc04c2a436e537767ac1aec709901594Devang Patel}
691d37ad247cc04c2a436e537767ac1aec709901594Devang Patel
692d37ad247cc04c2a436e537767ac1aec709901594Devang Patel/// ParseIntelMemOperand - Parse intel style memory operand.
693d37ad247cc04c2a436e537767ac1aec709901594Devang PatelX86Operand *X86AsmParser::ParseIntelMemOperand() {
694d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  const AsmToken &Tok = Parser.getTok();
695d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  SMLoc Start = Parser.getTok().getLoc(), End;
6967c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel  unsigned SegReg = 0;
697d37ad247cc04c2a436e537767ac1aec709901594Devang Patel
698d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  unsigned Size = getIntelMemOperandSize(Tok.getString());
699d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  if (Size) {
700d37ad247cc04c2a436e537767ac1aec709901594Devang Patel    Parser.Lex();
701d37ad247cc04c2a436e537767ac1aec709901594Devang Patel    assert (Tok.getString() == "PTR" && "Unexpected token!");
702d37ad247cc04c2a436e537767ac1aec709901594Devang Patel    Parser.Lex();
703d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  }
704d37ad247cc04c2a436e537767ac1aec709901594Devang Patel
705d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  if (getLexer().is(AsmToken::LBrac))
7067c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel    return ParseIntelBracExpression(SegReg, Size);
7077c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel
7087c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel  if (!ParseRegister(SegReg, Start, End)) {
7097c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel    // Handel SegReg : [ ... ]
7107c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel    if (getLexer().isNot(AsmToken::Colon))
7117c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel      return ErrorOperand(Start, "Expected ':' token!");
7127c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel    Parser.Lex(); // Eat :
7137c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel    if (getLexer().isNot(AsmToken::LBrac))
7147c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel      return ErrorOperand(Start, "Expected '[' token!");
7157c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel    return ParseIntelBracExpression(SegReg, Size);
7167c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel  }
717d37ad247cc04c2a436e537767ac1aec709901594Devang Patel
718d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext());
719d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  if (getParser().ParseExpression(Disp, End)) return 0;
720d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  return X86Operand::CreateMem(Disp, Start, End, Size);
721d37ad247cc04c2a436e537767ac1aec709901594Devang Patel}
722d37ad247cc04c2a436e537767ac1aec709901594Devang Patel
723d37ad247cc04c2a436e537767ac1aec709901594Devang PatelX86Operand *X86AsmParser::ParseIntelOperand() {
724d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  SMLoc Start = Parser.getTok().getLoc(), End;
725d37ad247cc04c2a436e537767ac1aec709901594Devang Patel
7260a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  // immediate.
727d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  if (getLexer().is(AsmToken::Integer) || getLexer().is(AsmToken::Real) ||
728d37ad247cc04c2a436e537767ac1aec709901594Devang Patel      getLexer().is(AsmToken::Minus)) {
729d37ad247cc04c2a436e537767ac1aec709901594Devang Patel    const MCExpr *Val;
730d37ad247cc04c2a436e537767ac1aec709901594Devang Patel    if (!getParser().ParseExpression(Val, End)) {
731d37ad247cc04c2a436e537767ac1aec709901594Devang Patel      End = Parser.getTok().getLoc();
732d37ad247cc04c2a436e537767ac1aec709901594Devang Patel      return X86Operand::CreateImm(Val, Start, End);
733d37ad247cc04c2a436e537767ac1aec709901594Devang Patel    }
734d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  }
735d37ad247cc04c2a436e537767ac1aec709901594Devang Patel
736d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  // register
7371aea430b8834f7bed3a14eda5027eac2133d6496Devang Patel  unsigned RegNo = 0;
7381aea430b8834f7bed3a14eda5027eac2133d6496Devang Patel  if (!ParseRegister(RegNo, Start, End)) {
7390a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel    End = Parser.getTok().getLoc();
740d37ad247cc04c2a436e537767ac1aec709901594Devang Patel    return X86Operand::CreateReg(RegNo, Start, End);
7410a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  }
7420a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel
743d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  // mem operand
744d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  return ParseIntelMemOperand();
7450a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel}
7460a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel
747dd929fc704054fa79cc1171354f95d91a5b62de2Devang PatelX86Operand *X86AsmParser::ParseATTOperand() {
74816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  switch (getLexer().getKind()) {
74916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  default:
750eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    // Parse a memory operand with no segment register.
751eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    return ParseMemOperand(0, Parser.getTok().getLoc());
75223075746a1418f281bc2a088ea85560bfd833599Chris Lattner  case AsmToken::Percent: {
753eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    // Read the register.
75423075746a1418f281bc2a088ea85560bfd833599Chris Lattner    unsigned RegNo;
75529ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    SMLoc Start, End;
75629ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    if (ParseRegister(RegNo, Start, End)) return 0;
7573c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes    if (RegNo == X86::EIZ || RegNo == X86::RIZ) {
7585efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer      Error(Start, "%eiz and %riz can only be used as index registers",
7595efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer            SMRange(Start, End));
7603c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes      return 0;
7613c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes    }
762f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
763eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    // If this is a segment register followed by a ':', then this is the start
764eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    // of a memory reference, otherwise this is a normal register reference.
765eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    if (getLexer().isNot(AsmToken::Colon))
766eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner      return X86Operand::CreateReg(RegNo, Start, End);
767f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
768f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
769eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    getParser().Lex(); // Eat the colon.
770eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    return ParseMemOperand(RegNo, Start);
77123075746a1418f281bc2a088ea85560bfd833599Chris Lattner  }
77216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  case AsmToken::Dollar: {
77316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // $42 -> immediate.
77418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    SMLoc Start = Parser.getTok().getLoc(), End;
775b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
7768c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar    const MCExpr *Val;
77754482b472a888c9efe003ad694ecf47b21878f0eChris Lattner    if (getParser().ParseExpression(Val, End))
778309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner      return 0;
779b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner    return X86Operand::CreateImm(Val, Start, End);
78016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
78116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
78216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar}
78316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
784eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner/// ParseMemOperand: segment: disp(basereg, indexreg, scale).  The '%ds:' prefix
785eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner/// has already been parsed if present.
786dd929fc704054fa79cc1171354f95d91a5b62de2Devang PatelX86Operand *X86AsmParser::ParseMemOperand(unsigned SegReg, SMLoc MemStart) {
787f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
78816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  // We have to disambiguate a parenthesized expression "(4+5)" from the start
78916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)".  The
79075f265fbbbb64ab060bf41c5a4677ce56014ce9fChris Lattner  // only way to do this without lookahead is to eat the '(' and see what is
79175f265fbbbb64ab060bf41c5a4677ce56014ce9fChris Lattner  // after it.
7928c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar  const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext());
79316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  if (getLexer().isNot(AsmToken::LParen)) {
79454482b472a888c9efe003ad694ecf47b21878f0eChris Lattner    SMLoc ExprEnd;
79554482b472a888c9efe003ad694ecf47b21878f0eChris Lattner    if (getParser().ParseExpression(Disp, ExprEnd)) return 0;
796f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
79716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // After parsing the base expression we could either have a parenthesized
79816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // memory address or not.  If not, return now.  If so, eat the (.
79916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    if (getLexer().isNot(AsmToken::LParen)) {
800c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar      // Unless we have a segment register, treat this as an immediate.
801309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner      if (SegReg == 0)
802b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar        return X86Operand::CreateMem(Disp, MemStart, ExprEnd);
8030a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner      return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd);
80416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    }
805f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
80616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // Eat the '('.
807b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
80816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  } else {
80916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // Okay, we have a '('.  We don't know if this is an expression or not, but
81016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // so we have to eat the ( to see beyond it.
81118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    SMLoc LParenLoc = Parser.getTok().getLoc();
812b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat the '('.
813f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
8147b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby    if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) {
81516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // Nothing to do here, fall into the code below with the '(' part of the
81616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // memory operand consumed.
81716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    } else {
818b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner      SMLoc ExprEnd;
819f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
82016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // It must be an parenthesized expression, parse it now.
821b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner      if (getParser().ParseParenExpression(Disp, ExprEnd))
822309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        return 0;
823f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
82416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // After parsing the base expression we could either have a parenthesized
82516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // memory address or not.  If not, return now.  If so, eat the (.
82616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      if (getLexer().isNot(AsmToken::LParen)) {
827c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar        // Unless we have a segment register, treat this as an immediate.
828309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        if (SegReg == 0)
829b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar          return X86Operand::CreateMem(Disp, LParenLoc, ExprEnd);
8300a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner        return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd);
83116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      }
832f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
83316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // Eat the '('.
834b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();
83516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    }
83616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
837f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
83816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  // If we reached here, then we just ate the ( of the memory operand.  Process
83916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  // the rest of the memory operand.
840022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
841f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
84229ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner  if (getLexer().is(AsmToken::Percent)) {
8435efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer    SMLoc StartLoc, EndLoc;
8445efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer    if (ParseRegister(BaseReg, StartLoc, EndLoc)) return 0;
8453c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes    if (BaseReg == X86::EIZ || BaseReg == X86::RIZ) {
8465efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer      Error(StartLoc, "eiz and riz can only be used as index registers",
8475efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer            SMRange(StartLoc, EndLoc));
8483c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes      return 0;
8493c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes    }
85029ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner  }
851f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
85216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  if (getLexer().is(AsmToken::Comma)) {
853b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat the comma.
85416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
85516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // Following the comma we should have either an index register, or a scale
85616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // value. We don't support the later form, but we want to parse it
85716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // correctly.
85816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    //
85916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // Not that even though it would be completely consistent to support syntax
8603c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes    // like "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this.
8617b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby    if (getLexer().is(AsmToken::Percent)) {
86229ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner      SMLoc L;
86329ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner      if (ParseRegister(IndexReg, L, L)) return 0;
864f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
86516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      if (getLexer().isNot(AsmToken::RParen)) {
86616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar        // Parse the scale amount:
86716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar        //  ::= ',' [scale-expression]
868309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        if (getLexer().isNot(AsmToken::Comma)) {
86918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan          Error(Parser.getTok().getLoc(),
870309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner                "expected comma in scale expression");
871309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner          return 0;
872309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        }
873b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan        Parser.Lex(); // Eat the comma.
87416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
87516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar        if (getLexer().isNot(AsmToken::RParen)) {
87618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan          SMLoc Loc = Parser.getTok().getLoc();
87716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
87816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar          int64_t ScaleVal;
87916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar          if (getParser().ParseAbsoluteExpression(ScaleVal))
880309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner            return 0;
881f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
88216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar          // Validate the scale amount.
883309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner          if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8){
884309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner            Error(Loc, "scale factor in address must be 1, 2, 4 or 8");
885309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner            return 0;
886309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner          }
88716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar          Scale = (unsigned)ScaleVal;
88816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar        }
88916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      }
89016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    } else if (getLexer().isNot(AsmToken::RParen)) {
891ee9102587e7f6fc95de9fc5731b341eeb9bfc3caDaniel Dunbar      // A scale amount without an index is ignored.
89216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // index.
89318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan      SMLoc Loc = Parser.getTok().getLoc();
89416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
89516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      int64_t Value;
89616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      if (getParser().ParseAbsoluteExpression(Value))
897309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        return 0;
898f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
899ee9102587e7f6fc95de9fc5731b341eeb9bfc3caDaniel Dunbar      if (Value != 1)
900ee9102587e7f6fc95de9fc5731b341eeb9bfc3caDaniel Dunbar        Warning(Loc, "scale factor without index register is ignored");
901ee9102587e7f6fc95de9fc5731b341eeb9bfc3caDaniel Dunbar      Scale = 1;
90216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    }
90316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
904f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
90516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  // Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
906309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner  if (getLexer().isNot(AsmToken::RParen)) {
90718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    Error(Parser.getTok().getLoc(), "unexpected token in memory operand");
908309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner    return 0;
909309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner  }
91018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  SMLoc MemEnd = Parser.getTok().getLoc();
911b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat the ')'.
912f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
9130a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner  return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale,
9140a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner                               MemStart, MemEnd);
915dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar}
916dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar
917dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patelbool X86AsmParser::
91838e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin KramerParseInstruction(StringRef Name, SMLoc NameLoc,
9199898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner                 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
920693173feefaa326fad0e386470846fb3199ba381Chris Lattner  StringRef PatchedName = Name;
92139e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar
922d8f717911dcdccb1a60b3049ea22c7767970dcb7Chris Lattner  // FIXME: Hack to recognize setneb as setne.
923d8f717911dcdccb1a60b3049ea22c7767970dcb7Chris Lattner  if (PatchedName.startswith("set") && PatchedName.endswith("b") &&
924d8f717911dcdccb1a60b3049ea22c7767970dcb7Chris Lattner      PatchedName != "setb" && PatchedName != "setnb")
925d8f717911dcdccb1a60b3049ea22c7767970dcb7Chris Lattner    PatchedName = PatchedName.substr(0, Name.size()-1);
926d8f717911dcdccb1a60b3049ea22c7767970dcb7Chris Lattner
92739e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar  // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}.
92839e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar  const MCExpr *ExtraImmOp = 0;
929428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes  if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) &&
93039e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      (PatchedName.endswith("ss") || PatchedName.endswith("sd") ||
93139e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar       PatchedName.endswith("ps") || PatchedName.endswith("pd"))) {
932428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes    bool IsVCMP = PatchedName.startswith("vcmp");
933428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes    unsigned SSECCIdx = IsVCMP ? 4 : 3;
93439e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar    unsigned SSEComparisonCode = StringSwitch<unsigned>(
935428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes      PatchedName.slice(SSECCIdx, PatchedName.size() - 2))
936cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("eq",          0)
937cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("lt",          1)
938cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("le",          2)
939cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("unord",       3)
940cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("neq",         4)
941cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("nlt",         5)
942cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("nle",         6)
943cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("ord",         7)
944cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("eq_uq",       8)
945cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("nge",         9)
946cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("ngt",      0x0A)
947cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("false",    0x0B)
948cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("neq_oq",   0x0C)
949cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("ge",       0x0D)
950cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("gt",       0x0E)
951cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("true",     0x0F)
952cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("eq_os",    0x10)
953cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("lt_oq",    0x11)
954cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("le_oq",    0x12)
955cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("unord_s",  0x13)
956cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("neq_us",   0x14)
957cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("nlt_uq",   0x15)
958cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("nle_uq",   0x16)
959cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("ord_s",    0x17)
960cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("eq_us",    0x18)
961cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("nge_uq",   0x19)
962cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("ngt_uq",   0x1A)
963cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("false_os", 0x1B)
964cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("neq_os",   0x1C)
965cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("ge_oq",    0x1D)
966cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("gt_oq",    0x1E)
967cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("true_us",  0x1F)
96839e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      .Default(~0U);
96939e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar    if (SSEComparisonCode != ~0U) {
97039e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      ExtraImmOp = MCConstantExpr::Create(SSEComparisonCode,
97139e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar                                          getParser().getContext());
97239e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      if (PatchedName.endswith("ss")) {
973428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes        PatchedName = IsVCMP ? "vcmpss" : "cmpss";
97439e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      } else if (PatchedName.endswith("sd")) {
975428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes        PatchedName = IsVCMP ? "vcmpsd" : "cmpsd";
97639e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      } else if (PatchedName.endswith("ps")) {
977428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes        PatchedName = IsVCMP ? "vcmpps" : "cmpps";
97839e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      } else {
97939e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar        assert(PatchedName.endswith("pd") && "Unexpected mnemonic!");
980428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes        PatchedName = IsVCMP ? "vcmppd" : "cmppd";
98139e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      }
98239e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar    }
98339e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar  }
984f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes
9851b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar  Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
98616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
987885f65b4a1c1ec80cd800a0617c57a2289472165Devang Patel  if (ExtraImmOp && !isParsingIntelSyntax())
98839e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar    Operands.push_back(X86Operand::CreateImm(ExtraImmOp, NameLoc, NameLoc));
989c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
9902544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  // Determine whether this is an instruction prefix.
9912544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  bool isPrefix =
992693173feefaa326fad0e386470846fb3199ba381Chris Lattner    Name == "lock" || Name == "rep" ||
993693173feefaa326fad0e386470846fb3199ba381Chris Lattner    Name == "repe" || Name == "repz" ||
994beb6898df8f96ccea4ae147587479b507bb3e491Rafael Espindola    Name == "repne" || Name == "repnz" ||
995bfd2d26159c87262fcf462ea442f99478a2093c9Rafael Espindola    Name == "rex64" || Name == "data16";
996c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
997c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
9982544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  // This does the actual operand parsing.  Don't parse any more if we have a
9992544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we
10002544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  // just want to parse the "lock" as the first instruction and the "incl" as
10012544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  // the next one.
10022544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  if (getLexer().isNot(AsmToken::EndOfStatement) && !isPrefix) {
10030db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar
10040db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar    // Parse '*' modifier.
10050db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar    if (getLexer().is(AsmToken::Star)) {
100618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan      SMLoc Loc = Parser.getTok().getLoc();
1007b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner      Operands.push_back(X86Operand::CreateToken("*", Loc));
1008b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex(); // Eat the star.
10090db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar    }
10100db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar
101116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // Read the first operand.
1012309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner    if (X86Operand *Op = ParseOperand())
1013309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner      Operands.push_back(Op);
1014cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    else {
1015cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      Parser.EatToEndOfStatement();
101616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      return true;
1017cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    }
101839e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar
101916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    while (getLexer().is(AsmToken::Comma)) {
1020b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();  // Eat the comma.
102116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
102216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // Parse and remember the operand.
1023309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner      if (X86Operand *Op = ParseOperand())
1024309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        Operands.push_back(Op);
1025cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      else {
1026cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        Parser.EatToEndOfStatement();
102716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar        return true;
1028cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      }
102916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    }
1030c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
1031cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    if (getLexer().isNot(AsmToken::EndOfStatement)) {
1032c146c4d47a7ec54c14e730c30bea821c34dc4c48Chris Lattner      SMLoc Loc = getLexer().getLoc();
1033cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      Parser.EatToEndOfStatement();
1034c146c4d47a7ec54c14e730c30bea821c34dc4c48Chris Lattner      return Error(Loc, "unexpected token in argument list");
1035cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    }
103616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
1037c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
10382544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  if (getLexer().is(AsmToken::EndOfStatement))
10392544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner    Parser.Lex(); // Consume the EndOfStatement
104076331754d4a06e2394c15ae8f4870f4aeaf5ca1fKevin Enderby  else if (isPrefix && getLexer().is(AsmToken::Slash))
104176331754d4a06e2394c15ae8f4870f4aeaf5ca1fKevin Enderby    Parser.Lex(); // Consume the prefix separator Slash
104216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
1043885f65b4a1c1ec80cd800a0617c57a2289472165Devang Patel  if (ExtraImmOp && isParsingIntelSyntax())
1044885f65b4a1c1ec80cd800a0617c57a2289472165Devang Patel    Operands.push_back(X86Operand::CreateImm(ExtraImmOp, NameLoc, NameLoc));
1045885f65b4a1c1ec80cd800a0617c57a2289472165Devang Patel
104698c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner  // This is a terrible hack to handle "out[bwl]? %al, (%dx)" ->
104798c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner  // "outb %al, %dx".  Out doesn't take a memory form, but this is a widely
104898c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner  // documented form in various unofficial manuals, so a lot of code uses it.
104998c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner  if ((Name == "outb" || Name == "outw" || Name == "outl" || Name == "out") &&
105098c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      Operands.size() == 3) {
105198c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner    X86Operand &Op = *(X86Operand*)Operands.back();
105298c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner    if (Op.isMem() && Op.Mem.SegReg == 0 &&
105398c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner        isa<MCConstantExpr>(Op.Mem.Disp) &&
105498c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner        cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
105598c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner        Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
105698c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      SMLoc Loc = Op.getEndLoc();
105798c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      Operands.back() = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
105898c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      delete &Op;
105998c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner    }
106098c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner  }
106100743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger  // Same hack for "in[bwl]? (%dx), %al" -> "inb %dx, %al".
106200743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger  if ((Name == "inb" || Name == "inw" || Name == "inl" || Name == "in") &&
106300743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger      Operands.size() == 3) {
106400743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger    X86Operand &Op = *(X86Operand*)Operands.begin()[1];
106500743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger    if (Op.isMem() && Op.Mem.SegReg == 0 &&
106600743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger        isa<MCConstantExpr>(Op.Mem.Disp) &&
106700743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger        cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
106800743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger        Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
106900743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger      SMLoc Loc = Op.getEndLoc();
107000743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger      Operands.begin()[1] = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
107100743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger      delete &Op;
107200743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger    }
107300743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger  }
107496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  // Transform "ins[bwl] %dx, %es:(%edi)" into "ins[bwl]"
107596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  if (Name.startswith("ins") && Operands.size() == 3 &&
107696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      (Name == "insb" || Name == "insw" || Name == "insl")) {
107796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand &Op = *(X86Operand*)Operands.begin()[1];
107896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand &Op2 = *(X86Operand*)Operands.begin()[2];
107996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    if (Op.isReg() && Op.getReg() == X86::DX && isDstOp(Op2)) {
108096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      Operands.pop_back();
108196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      Operands.pop_back();
108296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      delete &Op;
108396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      delete &Op2;
108496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    }
108596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  }
108696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger
108796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  // Transform "outs[bwl] %ds:(%esi), %dx" into "out[bwl]"
108896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  if (Name.startswith("outs") && Operands.size() == 3 &&
108996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      (Name == "outsb" || Name == "outsw" || Name == "outsl")) {
109096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand &Op = *(X86Operand*)Operands.begin()[1];
109196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand &Op2 = *(X86Operand*)Operands.begin()[2];
109296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    if (isSrcOp(Op) && Op2.isReg() && Op2.getReg() == X86::DX) {
109396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      Operands.pop_back();
109496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      Operands.pop_back();
109596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      delete &Op;
109696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      delete &Op2;
109796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    }
109896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  }
109996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger
110096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  // Transform "movs[bwl] %ds:(%esi), %es:(%edi)" into "movs[bwl]"
110196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  if (Name.startswith("movs") && Operands.size() == 3 &&
110296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      (Name == "movsb" || Name == "movsw" || Name == "movsl" ||
110359ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng       (is64BitMode() && Name == "movsq"))) {
110496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand &Op = *(X86Operand*)Operands.begin()[1];
110596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand &Op2 = *(X86Operand*)Operands.begin()[2];
110696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    if (isSrcOp(Op) && isDstOp(Op2)) {
110796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      Operands.pop_back();
110896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      Operands.pop_back();
110996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      delete &Op;
111096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      delete &Op2;
111196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    }
111296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  }
111396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  // Transform "lods[bwl] %ds:(%esi),{%al,%ax,%eax,%rax}" into "lods[bwl]"
111496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  if (Name.startswith("lods") && Operands.size() == 3 &&
111596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      (Name == "lods" || Name == "lodsb" || Name == "lodsw" ||
111659ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng       Name == "lodsl" || (is64BitMode() && Name == "lodsq"))) {
111796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]);
111896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand *Op2 = static_cast<X86Operand*>(Operands[2]);
111996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    if (isSrcOp(*Op1) && Op2->isReg()) {
112096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      const char *ins;
112196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      unsigned reg = Op2->getReg();
112296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      bool isLods = Name == "lods";
112396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      if (reg == X86::AL && (isLods || Name == "lodsb"))
112496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = "lodsb";
112596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      else if (reg == X86::AX && (isLods || Name == "lodsw"))
112696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = "lodsw";
112796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      else if (reg == X86::EAX && (isLods || Name == "lodsl"))
112896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = "lodsl";
112996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      else if (reg == X86::RAX && (isLods || Name == "lodsq"))
113096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = "lodsq";
113196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      else
113296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = NULL;
113396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      if (ins != NULL) {
113496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        Operands.pop_back();
113596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        Operands.pop_back();
113696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        delete Op1;
113796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        delete Op2;
113896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        if (Name != ins)
113996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger          static_cast<X86Operand*>(Operands[0])->setTokenValue(ins);
114096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      }
114196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    }
114296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  }
114396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  // Transform "stos[bwl] {%al,%ax,%eax,%rax},%es:(%edi)" into "stos[bwl]"
114496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  if (Name.startswith("stos") && Operands.size() == 3 &&
114596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      (Name == "stos" || Name == "stosb" || Name == "stosw" ||
114659ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng       Name == "stosl" || (is64BitMode() && Name == "stosq"))) {
114796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]);
114896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand *Op2 = static_cast<X86Operand*>(Operands[2]);
114996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    if (isDstOp(*Op2) && Op1->isReg()) {
115096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      const char *ins;
115196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      unsigned reg = Op1->getReg();
115296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      bool isStos = Name == "stos";
115396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      if (reg == X86::AL && (isStos || Name == "stosb"))
115496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = "stosb";
115596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      else if (reg == X86::AX && (isStos || Name == "stosw"))
115696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = "stosw";
115796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      else if (reg == X86::EAX && (isStos || Name == "stosl"))
115896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = "stosl";
115996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      else if (reg == X86::RAX && (isStos || Name == "stosq"))
116096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = "stosq";
116196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      else
116296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = NULL;
116396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      if (ins != NULL) {
116496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        Operands.pop_back();
116596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        Operands.pop_back();
116696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        delete Op1;
116796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        delete Op2;
116896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        if (Name != ins)
116996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger          static_cast<X86Operand*>(Operands[0])->setTokenValue(ins);
117096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      }
117196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    }
117296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  }
117396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger
1174e9e16a36d9ff355dab60e4b95673bf7a0cd27e86Chris Lattner  // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>.  Canonicalize to
1175ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner  // "shift <op>".
1176d5e7705a05947e60806b795880f09757e835f590Daniel Dunbar  if ((Name.startswith("shr") || Name.startswith("sar") ||
11778c24b0c6996a8f03ff32766f0695dcf19577af59Chris Lattner       Name.startswith("shl") || Name.startswith("sal") ||
11788c24b0c6996a8f03ff32766f0695dcf19577af59Chris Lattner       Name.startswith("rcl") || Name.startswith("rcr") ||
11798c24b0c6996a8f03ff32766f0695dcf19577af59Chris Lattner       Name.startswith("rol") || Name.startswith("ror")) &&
118047ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner      Operands.size() == 3) {
1181be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel    if (isParsingIntelSyntax()) {
11823b96e1fe3b695e6d845668ea90d75016f0f46a17Devang Patel      // Intel syntax
11833b96e1fe3b695e6d845668ea90d75016f0f46a17Devang Patel      X86Operand *Op1 = static_cast<X86Operand*>(Operands[2]);
11843b96e1fe3b695e6d845668ea90d75016f0f46a17Devang Patel      if (Op1->isImm() && isa<MCConstantExpr>(Op1->getImm()) &&
11853b96e1fe3b695e6d845668ea90d75016f0f46a17Devang Patel	  cast<MCConstantExpr>(Op1->getImm())->getValue() == 1) {
11863b96e1fe3b695e6d845668ea90d75016f0f46a17Devang Patel	delete Operands[2];
11873b96e1fe3b695e6d845668ea90d75016f0f46a17Devang Patel	Operands.pop_back();
11883b96e1fe3b695e6d845668ea90d75016f0f46a17Devang Patel      }
11893b96e1fe3b695e6d845668ea90d75016f0f46a17Devang Patel    } else {
11903b96e1fe3b695e6d845668ea90d75016f0f46a17Devang Patel      X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]);
11913b96e1fe3b695e6d845668ea90d75016f0f46a17Devang Patel      if (Op1->isImm() && isa<MCConstantExpr>(Op1->getImm()) &&
11923b96e1fe3b695e6d845668ea90d75016f0f46a17Devang Patel	  cast<MCConstantExpr>(Op1->getImm())->getValue() == 1) {
11933b96e1fe3b695e6d845668ea90d75016f0f46a17Devang Patel	delete Operands[1];
11943b96e1fe3b695e6d845668ea90d75016f0f46a17Devang Patel	Operands.erase(Operands.begin() + 1);
11953b96e1fe3b695e6d845668ea90d75016f0f46a17Devang Patel      }
119647ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner    }
1197f2de13f8d7bed958538bbd9dbeb9b15ea48456ccDaniel Dunbar  }
119815f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner
119915f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner  // Transforms "int $3" into "int3" as a size optimization.  We can't write an
120015f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner  // instalias with an immediate operand yet.
120115f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner  if (Name == "int" && Operands.size() == 2) {
120215f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner    X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]);
120315f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner    if (Op1->isImm() && isa<MCConstantExpr>(Op1->getImm()) &&
120415f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner        cast<MCConstantExpr>(Op1->getImm())->getValue() == 3) {
120515f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner      delete Operands[1];
120615f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner      Operands.erase(Operands.begin() + 1);
120715f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner      static_cast<X86Operand*>(Operands[0])->setTokenValue("int3");
120815f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner    }
120915f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner  }
1210c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
12119898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner  return false;
1212a3af370dc12f6d5100da5d614ab0a62da135569aDaniel Dunbar}
1213a3af370dc12f6d5100da5d614ab0a62da135569aDaniel Dunbar
1214dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patelbool X86AsmParser::
1215b8ba13f0096b560ee618512019ca86969a9fa772Devang PatelprocessInstruction(MCInst &Inst,
1216b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel                   const SmallVectorImpl<MCParsedAsmOperand*> &Ops) {
1217b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel  switch (Inst.getOpcode()) {
1218b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel  default: return false;
1219b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel  case X86::AND16i16: {
1220b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    if (!Inst.getOperand(0).isImm() ||
1221b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel        !isImmSExti16i8Value(Inst.getOperand(0).getImm()))
1222b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel      return false;
1223b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel
1224b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    MCInst TmpInst;
1225b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    TmpInst.setOpcode(X86::AND16ri8);
1226b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::AX));
1227b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::AX));
1228b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    TmpInst.addOperand(Inst.getOperand(0));
1229b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    Inst = TmpInst;
1230b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    return true;
1231b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel  }
1232b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel  case X86::AND32i32: {
1233b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    if (!Inst.getOperand(0).isImm() ||
1234b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel        !isImmSExti32i8Value(Inst.getOperand(0).getImm()))
1235b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel      return false;
1236b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel
1237b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    MCInst TmpInst;
1238b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    TmpInst.setOpcode(X86::AND32ri8);
1239b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::EAX));
1240b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::EAX));
1241b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    TmpInst.addOperand(Inst.getOperand(0));
1242b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    Inst = TmpInst;
1243b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    return true;
1244b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel  }
1245b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel  case X86::AND64i32: {
1246b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    if (!Inst.getOperand(0).isImm() ||
1247b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel        !isImmSExti64i8Value(Inst.getOperand(0).getImm()))
1248b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel      return false;
1249b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel
1250b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    MCInst TmpInst;
1251b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    TmpInst.setOpcode(X86::AND64ri8);
1252b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::RAX));
1253b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::RAX));
1254b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    TmpInst.addOperand(Inst.getOperand(0));
1255b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    Inst = TmpInst;
1256b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    return true;
1257b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel  }
1258ac0f0486022fb1798579c9a550154e839770efa9Devang Patel  case X86::XOR16i16: {
1259ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    if (!Inst.getOperand(0).isImm() ||
1260ac0f0486022fb1798579c9a550154e839770efa9Devang Patel        !isImmSExti16i8Value(Inst.getOperand(0).getImm()))
1261ac0f0486022fb1798579c9a550154e839770efa9Devang Patel      return false;
1262ac0f0486022fb1798579c9a550154e839770efa9Devang Patel
1263ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    MCInst TmpInst;
1264ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.setOpcode(X86::XOR16ri8);
1265ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::AX));
1266ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::AX));
1267ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(Inst.getOperand(0));
1268ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    Inst = TmpInst;
1269ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    return true;
1270ac0f0486022fb1798579c9a550154e839770efa9Devang Patel  }
1271ac0f0486022fb1798579c9a550154e839770efa9Devang Patel  case X86::XOR32i32: {
1272ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    if (!Inst.getOperand(0).isImm() ||
1273ac0f0486022fb1798579c9a550154e839770efa9Devang Patel        !isImmSExti32i8Value(Inst.getOperand(0).getImm()))
1274ac0f0486022fb1798579c9a550154e839770efa9Devang Patel      return false;
1275ac0f0486022fb1798579c9a550154e839770efa9Devang Patel
1276ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    MCInst TmpInst;
1277ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.setOpcode(X86::XOR32ri8);
1278ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::EAX));
1279ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::EAX));
1280ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(Inst.getOperand(0));
1281ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    Inst = TmpInst;
1282ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    return true;
1283ac0f0486022fb1798579c9a550154e839770efa9Devang Patel  }
1284ac0f0486022fb1798579c9a550154e839770efa9Devang Patel  case X86::XOR64i32: {
1285ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    if (!Inst.getOperand(0).isImm() ||
1286ac0f0486022fb1798579c9a550154e839770efa9Devang Patel        !isImmSExti64i8Value(Inst.getOperand(0).getImm()))
1287ac0f0486022fb1798579c9a550154e839770efa9Devang Patel      return false;
1288ac0f0486022fb1798579c9a550154e839770efa9Devang Patel
1289ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    MCInst TmpInst;
1290ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.setOpcode(X86::XOR64ri8);
1291ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::RAX));
1292ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::RAX));
1293ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(Inst.getOperand(0));
1294ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    Inst = TmpInst;
1295ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    return true;
1296ac0f0486022fb1798579c9a550154e839770efa9Devang Patel  }
1297ac0f0486022fb1798579c9a550154e839770efa9Devang Patel  case X86::OR16i16: {
1298ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    if (!Inst.getOperand(0).isImm() ||
1299ac0f0486022fb1798579c9a550154e839770efa9Devang Patel        !isImmSExti16i8Value(Inst.getOperand(0).getImm()))
1300ac0f0486022fb1798579c9a550154e839770efa9Devang Patel      return false;
1301ac0f0486022fb1798579c9a550154e839770efa9Devang Patel
1302ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    MCInst TmpInst;
1303ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.setOpcode(X86::OR16ri8);
1304ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::AX));
1305ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::AX));
1306ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(Inst.getOperand(0));
1307ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    Inst = TmpInst;
1308ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    return true;
1309ac0f0486022fb1798579c9a550154e839770efa9Devang Patel  }
1310ac0f0486022fb1798579c9a550154e839770efa9Devang Patel  case X86::OR32i32: {
1311ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    if (!Inst.getOperand(0).isImm() ||
1312ac0f0486022fb1798579c9a550154e839770efa9Devang Patel        !isImmSExti32i8Value(Inst.getOperand(0).getImm()))
1313ac0f0486022fb1798579c9a550154e839770efa9Devang Patel      return false;
1314ac0f0486022fb1798579c9a550154e839770efa9Devang Patel
1315ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    MCInst TmpInst;
1316ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.setOpcode(X86::OR32ri8);
1317ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::EAX));
1318ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::EAX));
1319ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(Inst.getOperand(0));
1320ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    Inst = TmpInst;
1321ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    return true;
1322ac0f0486022fb1798579c9a550154e839770efa9Devang Patel  }
1323ac0f0486022fb1798579c9a550154e839770efa9Devang Patel  case X86::OR64i32: {
1324ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    if (!Inst.getOperand(0).isImm() ||
1325ac0f0486022fb1798579c9a550154e839770efa9Devang Patel        !isImmSExti64i8Value(Inst.getOperand(0).getImm()))
1326ac0f0486022fb1798579c9a550154e839770efa9Devang Patel      return false;
1327ac0f0486022fb1798579c9a550154e839770efa9Devang Patel
1328ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    MCInst TmpInst;
1329ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.setOpcode(X86::OR64ri8);
1330ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::RAX));
1331ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::RAX));
1332ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(Inst.getOperand(0));
1333ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    Inst = TmpInst;
1334ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    return true;
1335ac0f0486022fb1798579c9a550154e839770efa9Devang Patel  }
1336ac0f0486022fb1798579c9a550154e839770efa9Devang Patel  case X86::CMP16i16: {
1337ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    if (!Inst.getOperand(0).isImm() ||
1338ac0f0486022fb1798579c9a550154e839770efa9Devang Patel        !isImmSExti16i8Value(Inst.getOperand(0).getImm()))
1339ac0f0486022fb1798579c9a550154e839770efa9Devang Patel      return false;
1340ac0f0486022fb1798579c9a550154e839770efa9Devang Patel
1341ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    MCInst TmpInst;
1342ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.setOpcode(X86::CMP16ri8);
1343ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::AX));
1344ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(Inst.getOperand(0));
1345ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    Inst = TmpInst;
1346ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    return true;
1347ac0f0486022fb1798579c9a550154e839770efa9Devang Patel  }
1348ac0f0486022fb1798579c9a550154e839770efa9Devang Patel  case X86::CMP32i32: {
1349ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    if (!Inst.getOperand(0).isImm() ||
1350ac0f0486022fb1798579c9a550154e839770efa9Devang Patel        !isImmSExti32i8Value(Inst.getOperand(0).getImm()))
1351ac0f0486022fb1798579c9a550154e839770efa9Devang Patel      return false;
1352ac0f0486022fb1798579c9a550154e839770efa9Devang Patel
1353ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    MCInst TmpInst;
1354ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.setOpcode(X86::CMP32ri8);
1355ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::EAX));
1356ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(Inst.getOperand(0));
1357ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    Inst = TmpInst;
1358ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    return true;
1359ac0f0486022fb1798579c9a550154e839770efa9Devang Patel  }
1360ac0f0486022fb1798579c9a550154e839770efa9Devang Patel  case X86::CMP64i32: {
1361ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    if (!Inst.getOperand(0).isImm() ||
1362ac0f0486022fb1798579c9a550154e839770efa9Devang Patel        !isImmSExti64i8Value(Inst.getOperand(0).getImm()))
1363ac0f0486022fb1798579c9a550154e839770efa9Devang Patel      return false;
1364ac0f0486022fb1798579c9a550154e839770efa9Devang Patel
1365ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    MCInst TmpInst;
1366ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.setOpcode(X86::CMP64ri8);
1367ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::RAX));
1368ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(Inst.getOperand(0));
1369ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    Inst = TmpInst;
1370ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    return true;
1371ac0f0486022fb1798579c9a550154e839770efa9Devang Patel  }
1372a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel  case X86::ADD16i16: {
1373a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    if (!Inst.getOperand(0).isImm() ||
1374a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel        !isImmSExti16i8Value(Inst.getOperand(0).getImm()))
1375a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel      return false;
1376a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel
1377a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    MCInst TmpInst;
1378a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.setOpcode(X86::ADD16ri8);
1379a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::AX));
1380a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::AX));
1381a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.addOperand(Inst.getOperand(0));
1382a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    Inst = TmpInst;
1383a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    return true;
1384a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel  }
1385a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel  case X86::ADD32i32: {
1386a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    if (!Inst.getOperand(0).isImm() ||
1387a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel        !isImmSExti32i8Value(Inst.getOperand(0).getImm()))
1388a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel      return false;
1389a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel
1390a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    MCInst TmpInst;
1391a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.setOpcode(X86::ADD32ri8);
1392a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::EAX));
1393a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::EAX));
1394a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.addOperand(Inst.getOperand(0));
1395a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    Inst = TmpInst;
1396a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    return true;
1397a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel  }
1398a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel  case X86::ADD64i32: {
1399a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    if (!Inst.getOperand(0).isImm() ||
1400a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel        !isImmSExti64i8Value(Inst.getOperand(0).getImm()))
1401a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel      return false;
1402a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel
1403a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    MCInst TmpInst;
1404a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.setOpcode(X86::ADD64ri8);
1405a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::RAX));
1406a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::RAX));
1407a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.addOperand(Inst.getOperand(0));
1408a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    Inst = TmpInst;
1409a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    return true;
1410a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel  }
1411a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel  case X86::SUB16i16: {
1412a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    if (!Inst.getOperand(0).isImm() ||
1413a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel        !isImmSExti16i8Value(Inst.getOperand(0).getImm()))
1414a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel      return false;
1415a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel
1416a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    MCInst TmpInst;
1417a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.setOpcode(X86::SUB16ri8);
1418a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::AX));
1419a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::AX));
1420a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.addOperand(Inst.getOperand(0));
1421a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    Inst = TmpInst;
1422a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    return true;
1423a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel  }
1424a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel  case X86::SUB32i32: {
1425a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    if (!Inst.getOperand(0).isImm() ||
1426a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel        !isImmSExti32i8Value(Inst.getOperand(0).getImm()))
1427a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel      return false;
1428a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel
1429a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    MCInst TmpInst;
1430a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.setOpcode(X86::SUB32ri8);
1431a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::EAX));
1432a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::EAX));
1433a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.addOperand(Inst.getOperand(0));
1434a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    Inst = TmpInst;
1435a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    return true;
1436a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel  }
1437a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel  case X86::SUB64i32: {
1438a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    if (!Inst.getOperand(0).isImm() ||
1439a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel        !isImmSExti64i8Value(Inst.getOperand(0).getImm()))
1440a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel      return false;
1441a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel
1442a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    MCInst TmpInst;
1443a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.setOpcode(X86::SUB64ri8);
1444a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::RAX));
1445a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::RAX));
1446a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.addOperand(Inst.getOperand(0));
1447a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    Inst = TmpInst;
1448a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    return true;
1449a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel  }
1450b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel  }
1451b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel}
1452b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel
1453b8ba13f0096b560ee618512019ca86969a9fa772Devang Patelbool X86AsmParser::
14547036f8be4df8a1a830ca01afe9497b035a5647d6Chris LattnerMatchAndEmitInstruction(SMLoc IDLoc,
14557c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner                        SmallVectorImpl<MCParsedAsmOperand*> &Operands,
14567036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner                        MCStreamer &Out) {
1457f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar  assert(!Operands.empty() && "Unexpect empty operand list!");
14587c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner  X86Operand *Op = static_cast<X86Operand*>(Operands[0]);
14597c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner  assert(Op->isToken() && "Leading operand should always be a mnemonic!");
14607c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner
14617c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner  // First, handle aliases that expand to multiple instructions.
14627c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner  // FIXME: This should be replaced with a real .td file alias mechanism.
146390fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner  // Also, MatchInstructionImpl should do actually *do* the EmitInstruction
146490fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner  // call.
14650966ec08610c02c8556105f2fff88a7e7247a549Andrew Trick  if (Op->getToken() == "fstsw" || Op->getToken() == "fstcw" ||
14668b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner      Op->getToken() == "fstsww" || Op->getToken() == "fstcww" ||
1467905f2e06691672c236ae864faf0ad7220afc2844Chris Lattner      Op->getToken() == "finit" || Op->getToken() == "fsave" ||
14685a378076a44ef3f507b91aa8e7715fabaec42074Kevin Enderby      Op->getToken() == "fstenv" || Op->getToken() == "fclex") {
14697c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner    MCInst Inst;
14707c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner    Inst.setOpcode(X86::WAIT);
1471cb5dca38157a48c734660746e7f7340d5db7c2dbJim Grosbach    Inst.setLoc(IDLoc);
14727c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner    Out.EmitInstruction(Inst);
1473f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar
14740bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner    const char *Repl =
14750bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner      StringSwitch<const char*>(Op->getToken())
14768b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner        .Case("finit",  "fninit")
14778b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner        .Case("fsave",  "fnsave")
14788b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner        .Case("fstcw",  "fnstcw")
14798b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner        .Case("fstcww",  "fnstcw")
1480905f2e06691672c236ae864faf0ad7220afc2844Chris Lattner        .Case("fstenv", "fnstenv")
14818b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner        .Case("fstsw",  "fnstsw")
14828b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner        .Case("fstsww", "fnstsw")
14838b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner        .Case("fclex",  "fnclex")
14840bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner        .Default(0);
14850bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner    assert(Repl && "Unknown wait-prefixed instruction");
1486b0f96facd6e6637cb71bbeaf2f4e006f0b6348e3Benjamin Kramer    delete Operands[0];
14870bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner    Operands[0] = X86Operand::CreateToken(Repl, IDLoc);
14887c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner  }
1489c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
1490a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  bool WasOriginallyInvalidOperand = false;
1491ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner  unsigned OrigErrorInfo;
14927036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner  MCInst Inst;
1493c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
1494c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // First, try a direct match.
1495be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel  switch (MatchInstructionImpl(Operands, Inst, OrigErrorInfo,
1496be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel                               isParsingIntelSyntax())) {
149719cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  default: break;
1498ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  case Match_Success:
1499b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    // Some instructions need post-processing to, for example, tweak which
1500b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    // encoding is selected. Loop on it while changes happen so the
1501b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    // individual transformations can chain off each other.
1502b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    while (processInstruction(Inst, Operands))
1503b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel      ;
1504b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel
1505cb5dca38157a48c734660746e7f7340d5db7c2dbJim Grosbach    Inst.setLoc(IDLoc);
15067036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner    Out.EmitInstruction(Inst);
1507c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar    return false;
1508ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  case Match_MissingFeature:
1509ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1510ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    return true;
1511b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar  case Match_ConversionFail:
1512b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar    return Error(IDLoc, "unable to convert operands to instruction");
1513a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  case Match_InvalidOperand:
1514a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner    WasOriginallyInvalidOperand = true;
1515a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner    break;
1516a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  case Match_MnemonicFail:
1517ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    break;
1518ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  }
1519c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
1520c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // FIXME: Ideally, we would only attempt suffix matches for things which are
1521c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // valid prefixes, and we could just infer the right unambiguous
1522c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // type. However, that requires substantially more matcher support than the
1523c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // following hack.
1524c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
1525c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // Change the operand to point to a temporary token.
1526c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  StringRef Base = Op->getToken();
1527f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar  SmallString<16> Tmp;
1528f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar  Tmp += Base;
1529f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar  Tmp += ' ';
1530f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar  Op->setTokenValue(Tmp.str());
1531c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
1532fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  // If this instruction starts with an 'f', then it is a floating point stack
1533fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  // instruction.  These come in up to three forms for 32-bit, 64-bit, and
1534fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  // 80-bit floating point, which use the suffixes s,l,t respectively.
1535fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  //
1536fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  // Otherwise, we assume that this may be an integer instruction, which comes
1537fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  // in 8/16/32/64-bit forms using the b,w,l,q suffixes respectively.
1538fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0";
1539fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner
1540c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // Check for the various suffix matches.
1541fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  Tmp[Base.size()] = Suffixes[0];
1542fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  unsigned ErrorInfoIgnore;
154319cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  unsigned Match1, Match2, Match3, Match4;
1544fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner
1545fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  Match1 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore);
1546fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  Tmp[Base.size()] = Suffixes[1];
1547fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  Match2 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore);
1548fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  Tmp[Base.size()] = Suffixes[2];
1549fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  Match3 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore);
1550fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  Tmp[Base.size()] = Suffixes[3];
1551fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  Match4 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore);
1552c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
1553c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // Restore the old token.
1554c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  Op->setTokenValue(Base);
1555c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
1556c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // If exactly one matched, then we treat that as a successful match (and the
1557c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // instruction will already have been filled in correctly, since the failing
1558c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // matches won't have modified it).
1559ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  unsigned NumSuccessfulMatches =
1560fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner    (Match1 == Match_Success) + (Match2 == Match_Success) +
1561fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner    (Match3 == Match_Success) + (Match4 == Match_Success);
15627036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner  if (NumSuccessfulMatches == 1) {
1563cb5dca38157a48c734660746e7f7340d5db7c2dbJim Grosbach    Inst.setLoc(IDLoc);
15647036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner    Out.EmitInstruction(Inst);
1565c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar    return false;
15667036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner  }
1567c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
1568ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  // Otherwise, the match failed, try to produce a decent error message.
1569f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar
157009062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar  // If we had multiple suffix matches, then identify this as an ambiguous
157109062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar  // match.
1572ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  if (NumSuccessfulMatches > 1) {
157309062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    char MatchChars[4];
157409062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    unsigned NumMatches = 0;
1575fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner    if (Match1 == Match_Success) MatchChars[NumMatches++] = Suffixes[0];
1576fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner    if (Match2 == Match_Success) MatchChars[NumMatches++] = Suffixes[1];
1577fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner    if (Match3 == Match_Success) MatchChars[NumMatches++] = Suffixes[2];
1578fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner    if (Match4 == Match_Success) MatchChars[NumMatches++] = Suffixes[3];
157909062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar
158009062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    SmallString<126> Msg;
158109062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    raw_svector_ostream OS(Msg);
158209062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    OS << "ambiguous instructions require an explicit suffix (could be ";
158309062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    for (unsigned i = 0; i != NumMatches; ++i) {
158409062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar      if (i != 0)
158509062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar        OS << ", ";
158609062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar      if (i + 1 == NumMatches)
158709062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar        OS << "or ";
158809062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar      OS << "'" << Base << MatchChars[i] << "'";
158909062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    }
159009062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    OS << ")";
159109062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    Error(IDLoc, OS.str());
1592ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    return true;
159309062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar  }
1594c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
1595a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  // Okay, we know that none of the variants matched successfully.
1596c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
1597a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  // If all of the instructions reported an invalid mnemonic, then the original
1598a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  // mnemonic was invalid.
1599fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  if ((Match1 == Match_MnemonicFail) && (Match2 == Match_MnemonicFail) &&
1600fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner      (Match3 == Match_MnemonicFail) && (Match4 == Match_MnemonicFail)) {
1601ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner    if (!WasOriginallyInvalidOperand) {
1602f82edaffb1a6d41bc89d86c69f53962e63621aadBenjamin Kramer      return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'",
1603f82edaffb1a6d41bc89d86c69f53962e63621aadBenjamin Kramer                   Op->getLocRange());
1604ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner    }
1605ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner
1606ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner    // Recover location info for the operand if we know which was the problem.
1607ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner    if (OrigErrorInfo != ~0U) {
1608f884012c93578912556de6ab89ecebab79b4ee31Chris Lattner      if (OrigErrorInfo >= Operands.size())
1609f884012c93578912556de6ab89ecebab79b4ee31Chris Lattner        return Error(IDLoc, "too few operands for instruction");
1610c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
1611d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner      X86Operand *Operand = (X86Operand*)Operands[OrigErrorInfo];
1612d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner      if (Operand->getStartLoc().isValid()) {
1613d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner        SMRange OperandRange = Operand->getLocRange();
1614d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner        return Error(Operand->getStartLoc(), "invalid operand for instruction",
1615d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner                     OperandRange);
1616d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner      }
1617ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner    }
1618ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner
1619d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner    return Error(IDLoc, "invalid operand for instruction");
1620a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  }
1621c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
1622ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  // If one instruction matched with a missing feature, report this as a
1623ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  // missing feature.
1624fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  if ((Match1 == Match_MissingFeature) + (Match2 == Match_MissingFeature) +
1625fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner      (Match3 == Match_MissingFeature) + (Match4 == Match_MissingFeature) == 1){
1626ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1627ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    return true;
1628ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  }
1629c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
1630a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  // If one instruction matched with an invalid operand, report this as an
1631a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  // operand failure.
1632fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  if ((Match1 == Match_InvalidOperand) + (Match2 == Match_InvalidOperand) +
1633fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner      (Match3 == Match_InvalidOperand) + (Match4 == Match_InvalidOperand) == 1){
1634a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner    Error(IDLoc, "invalid operand for instruction");
1635a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner    return true;
1636a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  }
1637c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
1638ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  // If all of these were an outright failure, report it in a useless way.
1639a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  Error(IDLoc, "unknown use of instruction mnemonic without a size suffix");
1640c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  return true;
1641c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar}
1642c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
1643c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
1644dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patelbool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
1645537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner  StringRef IDVal = DirectiveID.getIdentifier();
1646537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner  if (IDVal == ".word")
1647537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner    return ParseDirectiveWord(2, DirectiveID.getLoc());
1648bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng  else if (IDVal.startswith(".code"))
1649bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    return ParseDirectiveCode(IDVal, DirectiveID.getLoc());
1650be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel  else if (IDVal.startswith(".intel_syntax")) {
16510db58bfecea020ffcdfa1fc6458995371e1c3c50Devang Patel    getParser().setAssemblerDialect(1);
1652be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel    if (getLexer().isNot(AsmToken::EndOfStatement)) {
1653be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel      if(Parser.getTok().getString() == "noprefix") {
1654be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel	// FIXME : Handle noprefix
1655be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel	Parser.Lex();
1656be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel      } else
1657be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel	return true;
1658be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel    }
1659be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel    return false;
1660be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel  }
1661537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner  return true;
1662537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner}
1663537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner
1664537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner/// ParseDirectiveWord
1665537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner///  ::= .word [ expression (, expression)* ]
1666dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patelbool X86AsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
1667537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1668537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner    for (;;) {
1669537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner      const MCExpr *Value;
1670537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner      if (getParser().ParseExpression(Value))
1671537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner        return true;
1672537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner
1673537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner      getParser().getStreamer().EmitValue(Value, Size, 0 /*addrspace*/);
1674537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner
1675537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner      if (getLexer().is(AsmToken::EndOfStatement))
1676537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner        break;
1677537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner
1678537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner      // FIXME: Improve diagnostic.
1679537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner      if (getLexer().isNot(AsmToken::Comma))
1680537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner        return Error(L, "unexpected token in directive");
1681537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner      Parser.Lex();
1682537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner    }
1683537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner  }
1684537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner
1685537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner  Parser.Lex();
1686537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner  return false;
1687537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner}
1688537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner
1689bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng/// ParseDirectiveCode
1690bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng///  ::= .code32 | .code64
1691dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patelbool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
1692bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng  if (IDVal == ".code32") {
1693bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    Parser.Lex();
1694bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    if (is64BitMode()) {
1695bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng      SwitchMode();
1696bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng      getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
1697bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    }
1698bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng  } else if (IDVal == ".code64") {
1699bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    Parser.Lex();
1700bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    if (!is64BitMode()) {
1701bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng      SwitchMode();
1702bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng      getParser().getStreamer().EmitAssemblerFlag(MCAF_Code64);
1703bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    }
1704bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng  } else {
1705bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    return Error(L, "unexpected directive " + IDVal);
1706bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng  }
1707537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner
1708bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng  return false;
1709bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng}
1710537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner
1711537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner
1712e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callananextern "C" void LLVMInitializeX86AsmLexer();
1713e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan
1714092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar// Force static initialization.
1715092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbarextern "C" void LLVMInitializeX86AsmParser() {
1716dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patel  RegisterMCAsmParser<X86AsmParser> X(TheX86_32Target);
1717dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patel  RegisterMCAsmParser<X86AsmParser> Y(TheX86_64Target);
1718e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan  LLVMInitializeX86AsmLexer();
1719092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar}
17200e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar
17210692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER
17220692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION
17230e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar#include "X86GenAsmMatcher.inc"
1724