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"
114284e1795dd47d9638bb4fbd455ddb7e2e710e80Chad Rosier#include "llvm/ADT/APFloat.h"
1233d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner#include "llvm/ADT/SmallString.h"
1333d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner#include "llvm/ADT/SmallVector.h"
1433d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner#include "llvm/ADT/StringSwitch.h"
1533d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner#include "llvm/ADT/Twine.h"
16d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCExpr.h"
17d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCInst.h"
18d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCParser/MCAsmLexer.h"
19d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCParser/MCAsmParser.h"
20d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
21d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCRegisterInfo.h"
22d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCStreamer.h"
23d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCSubtargetInfo.h"
24d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCSymbol.h"
25d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCTargetAsmParser.h"
2616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar#include "llvm/Support/SourceMgr.h"
273e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h"
2809062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar#include "llvm/Support/raw_ostream.h"
29ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
30092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbarusing namespace llvm;
31092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar
32092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbarnamespace {
33c6b79ac88e52367dd2afdf03b1be81b10345c0bbBenjamin Kramerstruct X86Operand;
34092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar
35dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patelclass X86AsmParser : public MCTargetAsmParser {
36ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  MCSubtargetInfo &STI;
3716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  MCAsmParser &Parser;
386a020a71173a3ea7738a9df69982e85ddbfe0303Chad Rosier  ParseInstructionInfo *InstInfo;
3916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbarprivate:
4016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  MCAsmParser &getParser() const { return Parser; }
41a2edbabcb86f213eca6daeda5d801f8c7b1e44b2Daniel Dunbar
4216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
4316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
44d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner  bool Error(SMLoc L, const Twine &Msg,
45b4fdadef51ed254d9282356463c6b11ff8a102dfChad Rosier             ArrayRef<SMRange> Ranges = ArrayRef<SMRange>(),
467a2b624bb34374fe233f71cc5220d5ae0a0971cfChad Rosier             bool MatchingInlineAsm = false) {
477a2b624bb34374fe233f71cc5220d5ae0a0971cfChad Rosier    if (MatchingInlineAsm) return true;
48d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner    return Parser.Error(L, Msg, Ranges);
49d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner  }
5016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
51d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  X86Operand *ErrorOperand(SMLoc Loc, StringRef Msg) {
52d37ad247cc04c2a436e537767ac1aec709901594Devang Patel    Error(Loc, Msg);
53d37ad247cc04c2a436e537767ac1aec709901594Devang Patel    return 0;
54d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  }
55d37ad247cc04c2a436e537767ac1aec709901594Devang Patel
56309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner  X86Operand *ParseOperand();
570a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  X86Operand *ParseATTOperand();
580a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  X86Operand *ParseIntelOperand();
59c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier  X86Operand *ParseIntelOffsetOfOperator(SMLoc StartLoc);
60505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier  X86Operand *ParseIntelOperator(SMLoc StartLoc, unsigned OpKind);
615b0f1b37639d57dec72972fe445880a8a99d8674Chad Rosier  X86Operand *ParseIntelMemOperand(unsigned SegReg, SMLoc StartLoc);
627c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel  X86Operand *ParseIntelBracExpression(unsigned SegReg, unsigned Size);
63eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner  X86Operand *ParseMemOperand(unsigned SegReg, SMLoc StartLoc);
649c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby
655e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier  bool ParseIntelDotOperator(const MCExpr *Disp, const MCExpr **NewDisp,
665e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier                             SmallString<64> &Err);
6722f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier
689c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby  bool ParseDirectiveWord(unsigned Size, SMLoc L);
69bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng  bool ParseDirectiveCode(StringRef IDVal, SMLoc L);
709c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby
71b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel  bool processInstruction(MCInst &Inst,
72b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel                          const SmallVectorImpl<MCParsedAsmOperand*> &Ops);
73b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel
7484125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier  bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
757c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner                               SmallVectorImpl<MCParsedAsmOperand*> &Operands,
7684125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier                               MCStreamer &Out, unsigned &ErrorInfo,
7784125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier                               bool MatchingInlineAsm);
783246176838a47fa088b98772d4899063a9b7f731Chad Rosier
7996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  /// isSrcOp - Returns true if operand is either (%rsi) or %ds:%(rsi)
800f5ab7c5f392d8207a4b0c5bf1f8b274a9f410dfKevin Enderby  /// in 64bit mode or (%esi) or %es:(%esi) in 32bit mode.
8196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  bool isSrcOp(X86Operand &Op);
8296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger
830f5ab7c5f392d8207a4b0c5bf1f8b274a9f410dfKevin Enderby  /// isDstOp - Returns true if operand is either (%rdi) or %es:(%rdi)
840f5ab7c5f392d8207a4b0c5bf1f8b274a9f410dfKevin Enderby  /// in 64bit mode or (%edi) or %es:(%edi) in 32bit mode.
8596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  bool isDstOp(X86Operand &Op);
8696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger
8759ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  bool is64BitMode() const {
88ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    // FIXME: Can tablegen auto-generate this?
89ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    return (STI.getFeatureBits() & X86::Mode64Bit) != 0;
90ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
91bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng  void SwitchMode() {
92bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(X86::Mode64Bit));
93bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    setAvailableFeatures(FB);
94bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng  }
95ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
9654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  /// @name Auto-generated Matcher Functions
9754074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  /// {
98c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
990692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER
1000692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "X86GenAsmMatcher.inc"
101c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
1020e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar  /// }
10316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
10416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbarpublic:
105dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patel  X86AsmParser(MCSubtargetInfo &sti, MCAsmParser &parser)
1066a020a71173a3ea7738a9df69982e85ddbfe0303Chad Rosier    : MCTargetAsmParser(), STI(sti), Parser(parser), InstInfo(0) {
107c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
10854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar    // Initialize the set of available features.
109ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
11054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar  }
111bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky  virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
11216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
1136a020a71173a3ea7738a9df69982e85ddbfe0303Chad Rosier  virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
1146a020a71173a3ea7738a9df69982e85ddbfe0303Chad Rosier                                SMLoc NameLoc,
1159898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner                                SmallVectorImpl<MCParsedAsmOperand*> &Operands);
1169c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby
1179c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby  virtual bool ParseDirective(AsmToken DirectiveID);
118be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel
119be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel  bool isParsingIntelSyntax() {
1200db58bfecea020ffcdfa1fc6458995371e1c3c50Devang Patel    return getParser().getAssemblerDialect();
121be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel  }
12216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar};
12337dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner} // end anonymous namespace
12437dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner
125e9b466d4f09de3b46c0d0d1e71cabddc7cc9021bSean Callanan/// @name Auto-generated Match Functions
126f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes/// {
127e9b466d4f09de3b46c0d0d1e71cabddc7cc9021bSean Callanan
128b8d6e98e566724f58344d275a4bd675249bb713aChris Lattnerstatic unsigned MatchRegisterName(StringRef Name);
129e9b466d4f09de3b46c0d0d1e71cabddc7cc9021bSean Callanan
130e9b466d4f09de3b46c0d0d1e71cabddc7cc9021bSean Callanan/// }
13137dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner
13276bd9386f1e1487a49c7c34ff95078dea20e3154Craig Topperstatic bool isImmSExti16i8Value(uint64_t Value) {
133b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel  return ((                                  Value <= 0x000000000000007FULL)||
134b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel          (0x000000000000FF80ULL <= Value && Value <= 0x000000000000FFFFULL)||
135b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel          (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
136b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel}
137b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel
138b8ba13f0096b560ee618512019ca86969a9fa772Devang Patelstatic bool isImmSExti32i8Value(uint64_t Value) {
139b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel  return ((                                  Value <= 0x000000000000007FULL)||
140b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel          (0x00000000FFFFFF80ULL <= Value && Value <= 0x00000000FFFFFFFFULL)||
141b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel          (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
142b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel}
143b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel
144b8ba13f0096b560ee618512019ca86969a9fa772Devang Patelstatic bool isImmZExtu32u8Value(uint64_t Value) {
145b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    return (Value <= 0x00000000000000FFULL);
146b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel}
147b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel
148b8ba13f0096b560ee618512019ca86969a9fa772Devang Patelstatic bool isImmSExti64i8Value(uint64_t Value) {
149b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel  return ((                                  Value <= 0x000000000000007FULL)||
15076bd9386f1e1487a49c7c34ff95078dea20e3154Craig Topper          (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
151b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel}
152b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel
153b8ba13f0096b560ee618512019ca86969a9fa772Devang Patelstatic bool isImmSExti64i32Value(uint64_t Value) {
154b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel  return ((                                  Value <= 0x000000007FFFFFFFULL)||
15576bd9386f1e1487a49c7c34ff95078dea20e3154Craig Topper          (0xFFFFFFFF80000000ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
156b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel}
15737dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattnernamespace {
15816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
15916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar/// X86Operand - Instances of this class represent a parsed X86 machine
16016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar/// instruction.
16145220a84394758c86cc29ee0e3fe6738946fbcd0Chris Lattnerstruct X86Operand : public MCParsedAsmOperand {
1621f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner  enum KindTy {
16320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    Token,
16416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    Register,
16516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    Immediate,
166f9e008bf673a8eeb04766bfc99f51068608809d2Chad Rosier    Memory
16716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  } Kind;
16816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
16929ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner  SMLoc StartLoc, EndLoc;
1705a719fcb5ea91ec4e7af6fc2e48ec31774a859ddChad Rosier  SMLoc OffsetOfLoc;
171c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier  bool AddressOf;
172f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
173a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  struct TokOp {
174a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    const char *Data;
175a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    unsigned Length;
176a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
177a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
178a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  struct RegOp {
179a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    unsigned RegNo;
180a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
181a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
182a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  struct ImmOp {
183a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    const MCExpr *Val;
184a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    bool NeedAsmRewrite;
185a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
186a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
187a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  struct MemOp {
188a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    unsigned SegReg;
189a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    const MCExpr *Disp;
190a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    unsigned BaseReg;
191a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    unsigned IndexReg;
192a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    unsigned Scale;
193a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    unsigned Size;
194a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    bool NeedSizeDir;
195a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
196a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
19716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  union {
198a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    struct TokOp Tok;
199a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    struct RegOp Reg;
200a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    struct ImmOp Imm;
201a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    struct MemOp Mem;
202dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar  };
20316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
2040a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner  X86Operand(KindTy K, SMLoc Start, SMLoc End)
2051f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner    : Kind(K), StartLoc(Start), EndLoc(End) {}
206c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
2071f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner  /// getStartLoc - Get the location of the first token of this operand.
2081f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner  SMLoc getStartLoc() const { return StartLoc; }
2091f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner  /// getEndLoc - Get the location of the last token of this operand.
2101f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner  SMLoc getEndLoc() const { return EndLoc; }
2117d4e989da972c2e9c89dad2d4e8f6ff9e1c73394Chad Rosier  /// getLocRange - Get the range between the first and last token of this
2127d4e989da972c2e9c89dad2d4e8f6ff9e1c73394Chad Rosier  /// operand.
213d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner  SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
2145a719fcb5ea91ec4e7af6fc2e48ec31774a859ddChad Rosier  /// getOffsetOfLoc - Get the location of the offset operator.
2155a719fcb5ea91ec4e7af6fc2e48ec31774a859ddChad Rosier  SMLoc getOffsetOfLoc() const { return OffsetOfLoc; }
2161f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner
217b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbach  virtual void print(raw_ostream &OS) const {}
218b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar
21920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  StringRef getToken() const {
22020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    assert(Kind == Token && "Invalid access!");
22120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    return StringRef(Tok.Data, Tok.Length);
22220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  }
223c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  void setTokenValue(StringRef Value) {
224c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar    assert(Kind == Token && "Invalid access!");
225c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar    Tok.Data = Value.data();
226c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar    Tok.Length = Value.size();
227c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  }
22820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
22916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  unsigned getReg() const {
23016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    assert(Kind == Register && "Invalid access!");
23116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    return Reg.RegNo;
23216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
23316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
2348c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar  const MCExpr *getImm() const {
235022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Immediate && "Invalid access!");
236022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Imm.Val;
237022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
238022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar
239efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier  bool needAsmRewrite() const {
240efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier    assert(Kind == Immediate && "Invalid access!");
241efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier    return Imm.NeedAsmRewrite;
242efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier  }
243efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier
2448c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar  const MCExpr *getMemDisp() const {
245022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Memory && "Invalid access!");
246022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Mem.Disp;
247022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
248022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  unsigned getMemSegReg() const {
249022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Memory && "Invalid access!");
250022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Mem.SegReg;
251022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
252022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  unsigned getMemBaseReg() const {
253022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Memory && "Invalid access!");
254022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Mem.BaseReg;
255022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
256022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  unsigned getMemIndexReg() const {
257022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Memory && "Invalid access!");
258022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Mem.IndexReg;
259022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
260022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  unsigned getMemScale() const {
261022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Memory && "Invalid access!");
262022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Mem.Scale;
263022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
264022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar
265a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  bool isToken() const {return Kind == Token; }
26620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
26720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  bool isImm() const { return Kind == Immediate; }
268f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
26962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar  bool isImmSExti16i8() const {
2705fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar    if (!isImm())
2715fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar      return false;
2725fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar
27362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // If this isn't a constant expr, just assume it fits and let relaxation
27462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // handle it.
27562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
27662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    if (!CE)
27762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar      return true;
27862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar
27962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // Otherwise, check the value is in a range that makes sense for this
28062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // extension.
281b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    return isImmSExti16i8Value(CE->getValue());
28262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar  }
28362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar  bool isImmSExti32i8() const {
28462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    if (!isImm())
28562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar      return false;
2865fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel 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 isImmSExti32i8Value(CE->getValue());
2965fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar  }
297c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby  bool isImmZExtu32u8() const {
298c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby    if (!isImm())
299c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby      return false;
300c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby
301c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby    // If this isn't a constant expr, just assume it fits and let relaxation
302c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby    // handle it.
303c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
304c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby    if (!CE)
305c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby      return true;
306c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby
307c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby    // Otherwise, check the value is in a range that makes sense for this
308c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby    // extension.
309b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    return isImmZExtu32u8Value(CE->getValue());
310c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby  }
31162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar  bool isImmSExti64i8() const {
3121fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar    if (!isImm())
3131fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar      return false;
3141fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar
31562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // If this isn't a constant expr, just assume it fits and let relaxation
31662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // handle it.
31762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
31862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    if (!CE)
31962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar      return true;
32062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar
32162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // Otherwise, check the value is in a range that makes sense for this
32262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // extension.
323b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    return isImmSExti64i8Value(CE->getValue());
32462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar  }
32562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar  bool isImmSExti64i32() const {
32662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    if (!isImm())
32762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar      return false;
3281fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar
32962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // If this isn't a constant expr, just assume it fits and let relaxation
33062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // handle it.
33162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
33262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    if (!CE)
33362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar      return true;
33462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar
33562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // Otherwise, check the value is in a range that makes sense for this
33662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // extension.
337b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    return isImmSExti64i32Value(CE->getValue());
3381fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar  }
3391fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar
34096d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier  unsigned getMemSize() const {
34196d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier    assert(Kind == Memory && "Invalid access!");
34296d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier    return Mem.Size;
34396d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier  }
34496d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier
345a703fb9e5e86ed29f7334736f7c085ec81a2006fChad Rosier  bool isOffsetOf() const {
346c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier    return OffsetOfLoc.getPointer();
347a703fb9e5e86ed29f7334736f7c085ec81a2006fChad Rosier  }
348a703fb9e5e86ed29f7334736f7c085ec81a2006fChad Rosier
349c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier  bool needAddressOf() const {
350c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier    return AddressOf;
351c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier  }
352c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier
35396d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier  bool needSizeDirective() const {
35496d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier    assert(Kind == Memory && "Invalid access!");
35596d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier    return Mem.NeedSizeDir;
35696d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier  }
35796d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier
35820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  bool isMem() const { return Kind == Memory; }
35936b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier  bool isMem8() const {
360f9e008bf673a8eeb04766bfc99f51068608809d2Chad Rosier    return Kind == Memory && (!Mem.Size || Mem.Size == 8);
361c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
36236b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier  bool isMem16() const {
363f9e008bf673a8eeb04766bfc99f51068608809d2Chad Rosier    return Kind == Memory && (!Mem.Size || Mem.Size == 16);
364c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
36536b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier  bool isMem32() const {
366f9e008bf673a8eeb04766bfc99f51068608809d2Chad Rosier    return Kind == Memory && (!Mem.Size || Mem.Size == 32);
367c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
36836b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier  bool isMem64() const {
369f9e008bf673a8eeb04766bfc99f51068608809d2Chad Rosier    return Kind == Memory && (!Mem.Size || Mem.Size == 64);
370c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
37136b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier  bool isMem80() const {
372f9e008bf673a8eeb04766bfc99f51068608809d2Chad Rosier    return Kind == Memory && (!Mem.Size || Mem.Size == 80);
373c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
37436b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier  bool isMem128() const {
375f9e008bf673a8eeb04766bfc99f51068608809d2Chad Rosier    return Kind == Memory && (!Mem.Size || Mem.Size == 128);
376c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
37736b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier  bool isMem256() const {
378f9e008bf673a8eeb04766bfc99f51068608809d2Chad Rosier    return Kind == Memory && (!Mem.Size || Mem.Size == 256);
379c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
38020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
38175dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper  bool isMemVX32() const {
38275dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper    return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
38375dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper      getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM15;
38475dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper  }
38575dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper  bool isMemVY32() const {
38675dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper    return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
38775dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper      getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM15;
38875dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper  }
38975dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper  bool isMemVX64() const {
39075dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper    return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
39175dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper      getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM15;
39275dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper  }
39375dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper  bool isMemVY64() const {
39475dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper    return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
39575dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper      getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM15;
39675dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper  }
39775dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper
398b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  bool isAbsMem() const {
399b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
4007b9147afa7d1875353e1c1347b6b6cf71f548229Daniel Dunbar      !getMemIndexReg() && getMemScale() == 1;
401b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  }
402b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar
40320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  bool isReg() const { return Kind == Register; }
40420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
4059c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
4069c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar    // Add as immediates when possible.
4079c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
4089c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
4099c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar    else
4109c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar      Inst.addOperand(MCOperand::CreateExpr(Expr));
4119c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar  }
4129c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar
4135c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar  void addRegOperands(MCInst &Inst, unsigned N) const {
41420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    assert(N == 1 && "Invalid number of operands!");
41520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getReg()));
41620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  }
41720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
4185c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar  void addImmOperands(MCInst &Inst, unsigned N) const {
41920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    assert(N == 1 && "Invalid number of operands!");
4209c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar    addExpr(Inst, getImm());
42120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  }
42220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
42336b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier  void addMem8Operands(MCInst &Inst, unsigned N) const {
42436b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier    addMemOperands(Inst, N);
425c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
42636b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier  void addMem16Operands(MCInst &Inst, unsigned N) const {
42736b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier    addMemOperands(Inst, N);
428c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
42936b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier  void addMem32Operands(MCInst &Inst, unsigned N) const {
43036b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier    addMemOperands(Inst, N);
431c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
43236b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier  void addMem64Operands(MCInst &Inst, unsigned N) const {
43336b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier    addMemOperands(Inst, N);
434c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
43536b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier  void addMem80Operands(MCInst &Inst, unsigned N) const {
43636b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier    addMemOperands(Inst, N);
437c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
43836b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier  void addMem128Operands(MCInst &Inst, unsigned N) const {
43936b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier    addMemOperands(Inst, N);
440c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
44136b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier  void addMem256Operands(MCInst &Inst, unsigned N) const {
44275dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper    addMemOperands(Inst, N);
44375dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper  }
44475dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper  void addMemVX32Operands(MCInst &Inst, unsigned N) const {
44575dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper    addMemOperands(Inst, N);
44675dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper  }
44775dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper  void addMemVY32Operands(MCInst &Inst, unsigned N) const {
44875dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper    addMemOperands(Inst, N);
44975dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper  }
45075dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper  void addMemVX64Operands(MCInst &Inst, unsigned N) const {
45175dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper    addMemOperands(Inst, N);
45275dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper  }
45375dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper  void addMemVY64Operands(MCInst &Inst, unsigned N) const {
45436b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier    addMemOperands(Inst, N);
455c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
456c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel
4575c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar  void addMemOperands(MCInst &Inst, unsigned N) const {
458ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar    assert((N == 5) && "Invalid number of operands!");
45920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
46020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    Inst.addOperand(MCOperand::CreateImm(getMemScale()));
46120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemIndexReg()));
4629c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar    addExpr(Inst, getMemDisp());
463ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
464ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar  }
465ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar
466b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  void addAbsMemOperands(MCInst &Inst, unsigned N) const {
467b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    assert((N == 1) && "Invalid number of operands!");
468b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby    // Add as immediates when possible.
469b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
470b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
471b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby    else
472b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby      Inst.addOperand(MCOperand::CreateExpr(getMemDisp()));
473b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  }
474b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar
475b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner  static X86Operand *CreateToken(StringRef Str, SMLoc Loc) {
4763ebe59c892051375623fea55e977ff559fdb3323Jordan Rose    SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size());
477f82edaffb1a6d41bc89d86c69f53962e63621aadBenjamin Kramer    X86Operand *Res = new X86Operand(Token, Loc, EndLoc);
47829ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Tok.Data = Str.data();
47929ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Tok.Length = Str.size();
48020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    return Res;
48120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  }
48220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
483c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier  static X86Operand *CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc,
484c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier                               bool AddressOf = false,
485c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier                               SMLoc OffsetOfLoc = SMLoc()) {
4861f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner    X86Operand *Res = new X86Operand(Register, StartLoc, EndLoc);
48729ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Reg.RegNo = RegNo;
488c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier    Res->AddressOf = AddressOf;
489c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier    Res->OffsetOfLoc = OffsetOfLoc;
49029ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    return Res;
49116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
49220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
493efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier  static X86Operand *CreateImm(const MCExpr *Val, SMLoc StartLoc, SMLoc EndLoc,
494efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier                               bool NeedRewrite = true){
495b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner    X86Operand *Res = new X86Operand(Immediate, StartLoc, EndLoc);
49629ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Imm.Val = Val;
497efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier    Res->Imm.NeedAsmRewrite = NeedRewrite;
49829ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    return Res;
49916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
50020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
501b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  /// Create an absolute memory operand.
5024284e1795dd47d9638bb4fbd455ddb7e2e710e80Chad Rosier  static X86Operand *CreateMem(const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc,
5037109fbe98260d7a574762f5b9920d3d8e99052e3Chad Rosier                               unsigned Size = 0, bool NeedSizeDir = false) {
504b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc);
505b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    Res->Mem.SegReg   = 0;
506b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    Res->Mem.Disp     = Disp;
507b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    Res->Mem.BaseReg  = 0;
508b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    Res->Mem.IndexReg = 0;
5097b9147afa7d1875353e1c1347b6b6cf71f548229Daniel Dunbar    Res->Mem.Scale    = 1;
510c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel    Res->Mem.Size     = Size;
51196d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier    Res->Mem.NeedSizeDir = NeedSizeDir;
5127109fbe98260d7a574762f5b9920d3d8e99052e3Chad Rosier    Res->AddressOf = false;
513b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    return Res;
514b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  }
515b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar
516b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  /// Create a generalized memory operand.
517309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner  static X86Operand *CreateMem(unsigned SegReg, const MCExpr *Disp,
518309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner                               unsigned BaseReg, unsigned IndexReg,
519c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel                               unsigned Scale, SMLoc StartLoc, SMLoc EndLoc,
520c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier                               unsigned Size = 0, bool NeedSizeDir = false) {
521b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    // We should never just have a displacement, that should be parsed as an
522b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    // absolute memory operand.
523c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar    assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
524c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar
525022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    // The scale should always be one of {1,2,4,8}.
526022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
52716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar           "Invalid scale!");
5280a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner    X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc);
52929ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Mem.SegReg   = SegReg;
53029ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Mem.Disp     = Disp;
53129ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Mem.BaseReg  = BaseReg;
53229ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Mem.IndexReg = IndexReg;
53329ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Mem.Scale    = Scale;
534c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel    Res->Mem.Size     = Size;
53596d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier    Res->Mem.NeedSizeDir = NeedSizeDir;
536b789b949b60c9a28686e638f75b2640d16d7144eNAKAMURA Takumi    Res->AddressOf = false;
53729ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    return Res;
53816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
53916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar};
54016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
54137dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner} // end anonymous namespace.
54216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
543dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patelbool X86AsmParser::isSrcOp(X86Operand &Op) {
54459ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  unsigned basereg = is64BitMode() ? X86::RSI : X86::ESI;
54596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger
54696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  return (Op.isMem() &&
54796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    (Op.Mem.SegReg == 0 || Op.Mem.SegReg == X86::DS) &&
54896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    isa<MCConstantExpr>(Op.Mem.Disp) &&
54996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
55096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    Op.Mem.BaseReg == basereg && Op.Mem.IndexReg == 0);
55196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger}
55296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger
553dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patelbool X86AsmParser::isDstOp(X86Operand &Op) {
55459ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  unsigned basereg = is64BitMode() ? X86::RDI : X86::EDI;
55596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger
55636b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier  return Op.isMem() &&
5570f5ab7c5f392d8207a4b0c5bf1f8b274a9f410dfKevin Enderby    (Op.Mem.SegReg == 0 || Op.Mem.SegReg == X86::ES) &&
55896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    isa<MCConstantExpr>(Op.Mem.Disp) &&
55996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
56096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    Op.Mem.BaseReg == basereg && Op.Mem.IndexReg == 0;
56196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger}
56216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
563dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patelbool X86AsmParser::ParseRegister(unsigned &RegNo,
564dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patel                                 SMLoc &StartLoc, SMLoc &EndLoc) {
56523075746a1418f281bc2a088ea85560bfd833599Chris Lattner  RegNo = 0;
5668e70b5506ec0d7a6c2740bc89cd1b8f12a78b24fBenjamin Kramer  const AsmToken &PercentTok = Parser.getTok();
5678e70b5506ec0d7a6c2740bc89cd1b8f12a78b24fBenjamin Kramer  StartLoc = PercentTok.getLoc();
5688e70b5506ec0d7a6c2740bc89cd1b8f12a78b24fBenjamin Kramer
5698e70b5506ec0d7a6c2740bc89cd1b8f12a78b24fBenjamin Kramer  // If we encounter a %, ignore it. This code handles registers with and
5708e70b5506ec0d7a6c2740bc89cd1b8f12a78b24fBenjamin Kramer  // without the prefix, unprefixed registers can occur in cfi directives.
5718e70b5506ec0d7a6c2740bc89cd1b8f12a78b24fBenjamin Kramer  if (!isParsingIntelSyntax() && PercentTok.is(AsmToken::Percent))
572d37ad247cc04c2a436e537767ac1aec709901594Devang Patel    Parser.Lex(); // Eat percent token.
5737b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby
57418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
5753ebe59c892051375623fea55e977ff559fdb3323Jordan Rose  EndLoc = Tok.getEndLoc();
5763ebe59c892051375623fea55e977ff559fdb3323Jordan Rose
5771aea430b8834f7bed3a14eda5027eac2133d6496Devang Patel  if (Tok.isNot(AsmToken::Identifier)) {
578be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel    if (isParsingIntelSyntax()) return true;
5795efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer    return Error(StartLoc, "invalid register name",
5803ebe59c892051375623fea55e977ff559fdb3323Jordan Rose                 SMRange(StartLoc, EndLoc));
5811aea430b8834f7bed3a14eda5027eac2133d6496Devang Patel  }
58216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
5837b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby  RegNo = MatchRegisterName(Tok.getString());
584f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
58533d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner  // If the match failed, try the register name as lowercase.
58633d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner  if (RegNo == 0)
587590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer    RegNo = MatchRegisterName(Tok.getString().lower());
588c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
5895de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng  if (!is64BitMode()) {
5905de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng    // FIXME: This should be done using Requires<In32BitMode> and
5915de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng    // Requires<In64BitMode> so "eiz" usage in 64-bit instructions can be also
5925de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng    // checked.
5935de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng    // FIXME: Check AH, CH, DH, BH cannot be used in an instruction requiring a
5945de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng    // REX prefix.
5955de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng    if (RegNo == X86::RIZ ||
5965de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng        X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo) ||
5975de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng        X86II::isX86_64NonExtLowByteReg(RegNo) ||
5985de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng        X86II::isX86_64ExtendedReg(RegNo))
5995efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer      return Error(StartLoc, "register %"
6005efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer                   + Tok.getString() + " is only available in 64-bit mode",
6013ebe59c892051375623fea55e977ff559fdb3323Jordan Rose                   SMRange(StartLoc, EndLoc));
6025de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng  }
6033c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes
60433d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner  // Parse "%st" as "%st(0)" and "%st(1)", which is multiple tokens.
60533d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner  if (RegNo == 0 && (Tok.getString() == "st" || Tok.getString() == "ST")) {
606e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    RegNo = X86::ST0;
607e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    Parser.Lex(); // Eat 'st'
608f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
609e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    // Check to see if we have '(4)' after %st.
610e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    if (getLexer().isNot(AsmToken::LParen))
611e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner      return false;
612e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    // Lex the paren.
613e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    getParser().Lex();
614e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner
615e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    const AsmToken &IntTok = Parser.getTok();
616e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    if (IntTok.isNot(AsmToken::Integer))
617e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner      return Error(IntTok.getLoc(), "expected stack index");
618e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    switch (IntTok.getIntVal()) {
619e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 0: RegNo = X86::ST0; break;
620e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 1: RegNo = X86::ST1; break;
621e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 2: RegNo = X86::ST2; break;
622e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 3: RegNo = X86::ST3; break;
623e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 4: RegNo = X86::ST4; break;
624e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 5: RegNo = X86::ST5; break;
625e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 6: RegNo = X86::ST6; break;
626e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 7: RegNo = X86::ST7; break;
627e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    default: return Error(IntTok.getLoc(), "invalid stack index");
628e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    }
629f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
630e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    if (getParser().Lex().isNot(AsmToken::RParen))
631e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner      return Error(Parser.getTok().getLoc(), "expected ')'");
632f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
6333ebe59c892051375623fea55e977ff559fdb3323Jordan Rose    EndLoc = Parser.getTok().getEndLoc();
634e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    Parser.Lex(); // Eat ')'
635e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    return false;
636e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner  }
637f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
6383ebe59c892051375623fea55e977ff559fdb3323Jordan Rose  EndLoc = Parser.getTok().getEndLoc();
6393ebe59c892051375623fea55e977ff559fdb3323Jordan Rose
640645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner  // If this is "db[0-7]", match it as an alias
641645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner  // for dr[0-7].
642645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner  if (RegNo == 0 && Tok.getString().size() == 3 &&
643645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner      Tok.getString().startswith("db")) {
644645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    switch (Tok.getString()[2]) {
645645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '0': RegNo = X86::DR0; break;
646645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '1': RegNo = X86::DR1; break;
647645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '2': RegNo = X86::DR2; break;
648645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '3': RegNo = X86::DR3; break;
649645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '4': RegNo = X86::DR4; break;
650645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '5': RegNo = X86::DR5; break;
651645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '6': RegNo = X86::DR6; break;
652645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '7': RegNo = X86::DR7; break;
653645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    }
654f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
655645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    if (RegNo != 0) {
6563ebe59c892051375623fea55e977ff559fdb3323Jordan Rose      EndLoc = Parser.getTok().getEndLoc();
657645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner      Parser.Lex(); // Eat it.
658645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner      return false;
659645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    }
660645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner  }
661f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
6621aea430b8834f7bed3a14eda5027eac2133d6496Devang Patel  if (RegNo == 0) {
663be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel    if (isParsingIntelSyntax()) return true;
6645efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer    return Error(StartLoc, "invalid register name",
6653ebe59c892051375623fea55e977ff559fdb3323Jordan Rose                 SMRange(StartLoc, EndLoc));
6661aea430b8834f7bed3a14eda5027eac2133d6496Devang Patel  }
6670e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar
668b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat identifier token.
66916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  return false;
670092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar}
671092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar
672dd929fc704054fa79cc1171354f95d91a5b62de2Devang PatelX86Operand *X86AsmParser::ParseOperand() {
673be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel  if (isParsingIntelSyntax())
6740a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel    return ParseIntelOperand();
6750a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  return ParseATTOperand();
6760a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel}
6770a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel
678d37ad247cc04c2a436e537767ac1aec709901594Devang Patel/// getIntelMemOperandSize - Return intel memory operand size.
679d37ad247cc04c2a436e537767ac1aec709901594Devang Patelstatic unsigned getIntelMemOperandSize(StringRef OpStr) {
68066b64bec6021e3f38af090429c7e41d1180df5a9Chad Rosier  unsigned Size = StringSwitch<unsigned>(OpStr)
681f58ae5dfc1c939e34e660a21b4ea7d192a37a322Chad Rosier    .Cases("BYTE", "byte", 8)
682f58ae5dfc1c939e34e660a21b4ea7d192a37a322Chad Rosier    .Cases("WORD", "word", 16)
683f58ae5dfc1c939e34e660a21b4ea7d192a37a322Chad Rosier    .Cases("DWORD", "dword", 32)
684f58ae5dfc1c939e34e660a21b4ea7d192a37a322Chad Rosier    .Cases("QWORD", "qword", 64)
685f58ae5dfc1c939e34e660a21b4ea7d192a37a322Chad Rosier    .Cases("XWORD", "xword", 80)
686f58ae5dfc1c939e34e660a21b4ea7d192a37a322Chad Rosier    .Cases("XMMWORD", "xmmword", 128)
687f58ae5dfc1c939e34e660a21b4ea7d192a37a322Chad Rosier    .Cases("YMMWORD", "ymmword", 256)
68866b64bec6021e3f38af090429c7e41d1180df5a9Chad Rosier    .Default(0);
68966b64bec6021e3f38af090429c7e41d1180df5a9Chad Rosier  return Size;
6900a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel}
6910a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel
692dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosierenum IntelBracExprState {
693dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  IBES_START,
694dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  IBES_LBRAC,
695dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  IBES_RBRAC,
696dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  IBES_REGISTER,
697dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  IBES_REGISTER_STAR,
698dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  IBES_REGISTER_STAR_INTEGER,
699dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  IBES_INTEGER,
700dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  IBES_INTEGER_STAR,
701dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  IBES_INDEX_REGISTER,
702dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  IBES_IDENTIFIER,
703dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  IBES_DISP_EXPR,
704dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  IBES_MINUS,
705dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  IBES_ERROR
706dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier};
707dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier
708dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosierclass IntelBracExprStateMachine {
709dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  IntelBracExprState State;
710dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  unsigned BaseReg, IndexReg, Scale;
711dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  int64_t Disp;
712dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier
713dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  unsigned TmpReg;
714dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  int64_t TmpInteger;
715dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier
716dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  bool isPlus;
717dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier
718dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosierpublic:
719dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  IntelBracExprStateMachine(MCAsmParser &parser) :
720dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    State(IBES_START), BaseReg(0), IndexReg(0), Scale(1), Disp(0),
721dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    TmpReg(0), TmpInteger(0), isPlus(true) {}
722dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier
723dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  unsigned getBaseReg() { return BaseReg; }
724dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  unsigned getIndexReg() { return IndexReg; }
725dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  unsigned getScale() { return Scale; }
726dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  int64_t getDisp() { return Disp; }
727dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  bool isValidEndState() { return State == IBES_RBRAC; }
728dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier
729dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  void onPlus() {
730dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    switch (State) {
731dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    default:
732dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_ERROR;
733dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
734dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case IBES_INTEGER:
735dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_START;
736dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      if (isPlus)
737dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        Disp += TmpInteger;
738dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      else
739dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        Disp -= TmpInteger;
740dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
741dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case IBES_REGISTER:
742dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_START;
743dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      // If we already have a BaseReg, then assume this is the IndexReg with a
744dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      // scale of 1.
745dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      if (!BaseReg) {
746dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        BaseReg = TmpReg;
747dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      } else {
748dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        assert (!IndexReg && "BaseReg/IndexReg already set!");
749dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        IndexReg = TmpReg;
750dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        Scale = 1;
751dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      }
752dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
753dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case IBES_INDEX_REGISTER:
754dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_START;
755dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
756dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    }
757dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    isPlus = true;
758dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  }
759dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  void onMinus() {
760dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    switch (State) {
761dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    default:
762dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_ERROR;
763dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
764dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case IBES_START:
765dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_MINUS;
766dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
767dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case IBES_INTEGER:
768dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_START;
769dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      if (isPlus)
770dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        Disp += TmpInteger;
771dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      else
772dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        Disp -= TmpInteger;
773dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
774dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case IBES_REGISTER:
775dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_START;
776dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      // If we already have a BaseReg, then assume this is the IndexReg with a
777dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      // scale of 1.
778dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      if (!BaseReg) {
779dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        BaseReg = TmpReg;
780dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      } else {
781dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        assert (!IndexReg && "BaseReg/IndexReg already set!");
782dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        IndexReg = TmpReg;
783dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        Scale = 1;
784dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      }
785dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
786dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case IBES_INDEX_REGISTER:
787dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_START;
788dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
789dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    }
790dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    isPlus = false;
791dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  }
792dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  void onRegister(unsigned Reg) {
793dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    switch (State) {
794dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    default:
795dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_ERROR;
796dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
797dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case IBES_START:
798dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_REGISTER;
799dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      TmpReg = Reg;
800dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
801dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case IBES_INTEGER_STAR:
802dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      assert (!IndexReg && "IndexReg already set!");
803dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_INDEX_REGISTER;
804dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      IndexReg = Reg;
805dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      Scale = TmpInteger;
806dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
807dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    }
808dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  }
809dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  void onDispExpr() {
810dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    switch (State) {
811dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    default:
812dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_ERROR;
813dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
814dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case IBES_START:
815dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_DISP_EXPR;
816dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
817dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    }
818dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  }
819dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  void onInteger(int64_t TmpInt) {
820dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    switch (State) {
821dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    default:
822dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_ERROR;
823dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
824dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case IBES_START:
825dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_INTEGER;
826dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      TmpInteger = TmpInt;
827dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
828dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case IBES_MINUS:
829dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_INTEGER;
830dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      TmpInteger = TmpInt;
831dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
832dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case IBES_REGISTER_STAR:
833dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      assert (!IndexReg && "IndexReg already set!");
834dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_INDEX_REGISTER;
835dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      IndexReg = TmpReg;
836dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      Scale = TmpInt;
837dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
838dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    }
839dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  }
840dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  void onStar() {
841dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    switch (State) {
842dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    default:
843dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_ERROR;
844dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
845dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case IBES_INTEGER:
846dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_INTEGER_STAR;
847dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
848dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case IBES_REGISTER:
849dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_REGISTER_STAR;
850dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
851dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    }
852dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  }
853dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  void onLBrac() {
854dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    switch (State) {
855dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    default:
856dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_ERROR;
857dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
858dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case IBES_RBRAC:
859dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_START;
860dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      isPlus = true;
861dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
862dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    }
863dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  }
864dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  void onRBrac() {
865dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    switch (State) {
866dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    default:
867dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_ERROR;
868dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
869dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case IBES_DISP_EXPR:
870dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_RBRAC;
871dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
872dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case IBES_INTEGER:
873dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_RBRAC;
874dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      if (isPlus)
875dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        Disp += TmpInteger;
876dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      else
877dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        Disp -= TmpInteger;
878dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
879dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case IBES_REGISTER:
880dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_RBRAC;
881dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      // If we already have a BaseReg, then assume this is the IndexReg with a
882dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      // scale of 1.
883dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      if (!BaseReg) {
884dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        BaseReg = TmpReg;
885dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      } else {
886dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        assert (!IndexReg && "BaseReg/IndexReg already set!");
887dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        IndexReg = TmpReg;
888dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        Scale = 1;
889dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      }
890dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
891dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case IBES_INDEX_REGISTER:
892dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_RBRAC;
893dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
894dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    }
895dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  }
896dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier};
897dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier
89865c88929e718f4fb0f57afb4c95b2e570759e99fChad RosierX86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg,
8997c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel                                                   unsigned Size) {
9004284e1795dd47d9638bb4fbd455ddb7e2e710e80Chad Rosier  const AsmToken &Tok = Parser.getTok();
9013ebe59c892051375623fea55e977ff559fdb3323Jordan Rose  SMLoc Start = Tok.getLoc(), End = Tok.getEndLoc();
902c798cc42831150f678b080c0994c1cc024bae653Devang Patel
903d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  // Eat '['
904d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  if (getLexer().isNot(AsmToken::LBrac))
905d37ad247cc04c2a436e537767ac1aec709901594Devang Patel    return ErrorOperand(Start, "Expected '[' token!");
906d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  Parser.Lex();
90736b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier
908dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  unsigned TmpReg = 0;
909dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier
910dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  // Try to handle '[' 'symbol' ']'
911d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  if (getLexer().is(AsmToken::Identifier)) {
912dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    if (ParseRegister(TmpReg, Start, End)) {
913dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      const MCExpr *Disp;
914cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach      if (getParser().parseExpression(Disp, End))
915dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        return 0;
916dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier
917d37ad247cc04c2a436e537767ac1aec709901594Devang Patel      if (getLexer().isNot(AsmToken::RBrac))
9183ebe59c892051375623fea55e977ff559fdb3323Jordan Rose        return ErrorOperand(Parser.getTok().getLoc(), "Expected ']' token!");
9194fb25b7d799ea27a2c98a4d9bcf7469cc685db47Chad Rosier      // Adjust the EndLoc due to the ']'.
9204fb25b7d799ea27a2c98a4d9bcf7469cc685db47Chad Rosier      End = SMLoc::getFromPointer(Parser.getTok().getEndLoc().getPointer()-1);
92185d5aaecd03ca4bc6e406ee88c72a4ba8878bb2bDevang Patel      Parser.Lex();
922c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier      return X86Operand::CreateMem(Disp, Start, End, Size);
92385d5aaecd03ca4bc6e406ee88c72a4ba8878bb2bDevang Patel    }
9242fbc239e4fbdd12c24fb2cf9e3e915861fc12030Chad Rosier  }
9252fbc239e4fbdd12c24fb2cf9e3e915861fc12030Chad Rosier
926dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  // Parse [ BaseReg + Scale*IndexReg + Disp ].
927dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  bool Done = false;
928dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  IntelBracExprStateMachine SM(Parser);
929dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier
930dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  // If we parsed a register, then the end loc has already been set and
931dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  // the identifier has already been lexed.  We also need to update the
932dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  // state.
933dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  if (TmpReg)
934dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    SM.onRegister(TmpReg);
935dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier
936dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  const MCExpr *Disp = 0;
937dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  while (!Done) {
938dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    bool UpdateLocLex = true;
939dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier
940dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    // The period in the dot operator (e.g., [ebx].foo.bar) is parsed as an
941dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    // identifier.  Don't try an parse it as a register.
942dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    if (Tok.getString().startswith("."))
943dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
944dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier
945dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    switch (getLexer().getKind()) {
946dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    default: {
947dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      if (SM.isValidEndState()) {
948dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        Done = true;
949dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        break;
950dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      }
951dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      return ErrorOperand(Tok.getLoc(), "Unexpected token!");
952dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    }
953dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case AsmToken::Identifier: {
954dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      // This could be a register or a displacement expression.
955dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      if(!ParseRegister(TmpReg, Start, End)) {
956dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        SM.onRegister(TmpReg);
957dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        UpdateLocLex = false;
958dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        break;
959cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach      } else if (!getParser().parseExpression(Disp, End)) {
960dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        SM.onDispExpr();
961dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        UpdateLocLex = false;
962dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        break;
963dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      }
964dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      return ErrorOperand(Tok.getLoc(), "Unexpected identifier!");
965dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    }
966dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case AsmToken::Integer: {
9674284e1795dd47d9638bb4fbd455ddb7e2e710e80Chad Rosier      int64_t Val = Tok.getIntVal();
968dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      SM.onInteger(Val);
969dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
970f2d213745e07e884c1616f2f3d0b78f9e918e5dbDevang Patel    }
971dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case AsmToken::Plus:    SM.onPlus(); break;
972dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case AsmToken::Minus:   SM.onMinus(); break;
973dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case AsmToken::Star:    SM.onStar(); break;
974dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case AsmToken::LBrac:   SM.onLBrac(); break;
975dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case AsmToken::RBrac:   SM.onRBrac(); break;
976dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    }
977dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    if (!Done && UpdateLocLex) {
978dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      End = Tok.getLoc();
979dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      Parser.Lex(); // Consume the token.
9802fbc239e4fbdd12c24fb2cf9e3e915861fc12030Chad Rosier    }
9812fbc239e4fbdd12c24fb2cf9e3e915861fc12030Chad Rosier  }
982c798cc42831150f678b080c0994c1cc024bae653Devang Patel
983dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  if (!Disp)
984dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    Disp = MCConstantExpr::Create(SM.getDisp(), getContext());
985fdd3b30151bc391efce74f4592a9a3bb595565a2Devang Patel
986ddb53ef4a8aa526c293ff316c2134bf1629e6812Chad Rosier  // Parse the dot operator (e.g., [ebx].foo.bar).
9875e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier  if (Tok.getString().startswith(".")) {
9885e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier    SmallString<64> Err;
9895e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier    const MCExpr *NewDisp;
9905e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier    if (ParseIntelDotOperator(Disp, &NewDisp, Err))
9915e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier      return ErrorOperand(Tok.getLoc(), Err);
9925e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier
9933ebe59c892051375623fea55e977ff559fdb3323Jordan Rose    End = Parser.getTok().getEndLoc();
9945e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier    Parser.Lex();  // Eat the field.
9955e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier    Disp = NewDisp;
9965e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier  }
99722f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier
998dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  int BaseReg = SM.getBaseReg();
999dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  int IndexReg = SM.getIndexReg();
1000dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier
1001fdd3b30151bc391efce74f4592a9a3bb595565a2Devang Patel  // handle [-42]
1002dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  if (!BaseReg && !IndexReg) {
1003dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    if (!SegReg)
1004dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      return X86Operand::CreateMem(Disp, Start, End);
1005dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    else
1006dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, Start, End, Size);
1007dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  }
1008fdd3b30151bc391efce74f4592a9a3bb595565a2Devang Patel
1009dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  int Scale = SM.getScale();
1010d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale,
1011c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier                               Start, End, Size);
1012d37ad247cc04c2a436e537767ac1aec709901594Devang Patel}
1013d37ad247cc04c2a436e537767ac1aec709901594Devang Patel
1014d37ad247cc04c2a436e537767ac1aec709901594Devang Patel/// ParseIntelMemOperand - Parse intel style memory operand.
10155b0f1b37639d57dec72972fe445880a8a99d8674Chad RosierX86Operand *X86AsmParser::ParseIntelMemOperand(unsigned SegReg, SMLoc Start) {
1016d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  const AsmToken &Tok = Parser.getTok();
1017c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier  SMLoc End;
1018d37ad247cc04c2a436e537767ac1aec709901594Devang Patel
1019d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  unsigned Size = getIntelMemOperandSize(Tok.getString());
1020d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  if (Size) {
1021d37ad247cc04c2a436e537767ac1aec709901594Devang Patel    Parser.Lex();
1022f58ae5dfc1c939e34e660a21b4ea7d192a37a322Chad Rosier    assert ((Tok.getString() == "PTR" || Tok.getString() == "ptr") &&
1023f58ae5dfc1c939e34e660a21b4ea7d192a37a322Chad Rosier            "Unexpected token!");
1024d37ad247cc04c2a436e537767ac1aec709901594Devang Patel    Parser.Lex();
1025d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  }
1026d37ad247cc04c2a436e537767ac1aec709901594Devang Patel
1027c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier  if (getLexer().is(AsmToken::LBrac))
10287c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel    return ParseIntelBracExpression(SegReg, Size);
10297c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel
10307c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel  if (!ParseRegister(SegReg, Start, End)) {
10317c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel    // Handel SegReg : [ ... ]
10327c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel    if (getLexer().isNot(AsmToken::Colon))
10337c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel      return ErrorOperand(Start, "Expected ':' token!");
10347c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel    Parser.Lex(); // Eat :
10357c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel    if (getLexer().isNot(AsmToken::LBrac))
10367c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel      return ErrorOperand(Start, "Expected '[' token!");
10377c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel    return ParseIntelBracExpression(SegReg, Size);
10387c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel  }
1039d37ad247cc04c2a436e537767ac1aec709901594Devang Patel
1040d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext());
1041cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach  if (getParser().parseExpression(Disp, End))
10423ebe59c892051375623fea55e977ff559fdb3323Jordan Rose    return 0;
104396d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier
104496d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier  bool NeedSizeDir = false;
1045c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier  bool IsVarDecl = false;
1046c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier  if (isParsingInlineAsm()) {
104796d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier    if (const MCSymbolRefExpr *SymRef = dyn_cast<MCSymbolRefExpr>(Disp)) {
104896d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier      const MCSymbol &Sym = SymRef->getSymbol();
104996d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier      // FIXME: The SemaLookup will fail if the name is anything other then an
105096d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier      // identifier.
105196d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier      // FIXME: Pass a valid SMLoc.
1052505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier      unsigned tLength, tSize, tType;
1053505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier      SemaCallback->LookupInlineAsmIdentifier(Sym.getName(), NULL, tLength,
1054505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier                                              tSize, tType, IsVarDecl);
1055c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier      if (!Size)
1056505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier        Size = tType * 8; // Size is in terms of bits in this context.
105796d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier      NeedSizeDir = Size > 0;
105896d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier    }
105996d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier  }
10602a784131fed4bc99c0ae96b5252a3fe0079a3079Chad Rosier  if (!isParsingInlineAsm())
1061c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier    return X86Operand::CreateMem(Disp, Start, End, Size);
1062c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier  else {
1063c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier    // If this is not a VarDecl then assume it is a FuncDecl or some other label
1064c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier    // reference.  We need an 'r' constraint here, so we need to create register
1065c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier    // operand to ensure proper matching.  Just pick a GPR based on the size of
1066c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier    // a pointer.
1067c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier    if (!IsVarDecl) {
1068c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier      unsigned RegNo = is64BitMode() ? X86::RBX : X86::EBX;
1069c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier      return X86Operand::CreateReg(RegNo, Start, End, /*AddressOf=*/true);
1070c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier    }
1071c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier
1072d4d96acb9117574510390af700ec0eca375f58f2Chad Rosier    // When parsing inline assembly we set the base register to a non-zero value
1073d4d96acb9117574510390af700ec0eca375f58f2Chad Rosier    // as we don't know the actual value at this time.  This is necessary to
1074d4d96acb9117574510390af700ec0eca375f58f2Chad Rosier    // get the matching correct in some cases.
10752a784131fed4bc99c0ae96b5252a3fe0079a3079Chad Rosier    return X86Operand::CreateMem(/*SegReg*/0, Disp, /*BaseReg*/1, /*IndexReg*/0,
1076c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier                                 /*Scale*/1, Start, End, Size, NeedSizeDir);
1077c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier  }
1078c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier}
1079c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier
108022f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier/// Parse the '.' operator.
10815e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosierbool X86AsmParser::ParseIntelDotOperator(const MCExpr *Disp,
10825e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier                                         const MCExpr **NewDisp,
10835e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier                                         SmallString<64> &Err) {
108422f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier  AsmToken Tok = *&Parser.getTok();
10855e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier  uint64_t OrigDispVal, DotDispVal;
10865e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier
10875e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier  // FIXME: Handle non-constant expressions.
10885e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier  if (const MCConstantExpr *OrigDisp = dyn_cast<MCConstantExpr>(Disp)) {
10895e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier    OrigDispVal = OrigDisp->getValue();
10905e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier  } else {
10915e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier    Err = "Non-constant offsets are not supported!";
10925e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier    return true;
10935e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier  }
109422f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier
109522f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier  // Drop the '.'.
109622f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier  StringRef DotDispStr = Tok.getString().drop_front(1);
109722f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier
109822f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier  // .Imm gets lexed as a real.
109922f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier  if (Tok.is(AsmToken::Real)) {
110022f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier    APInt DotDisp;
110122f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier    DotDispStr.getAsInteger(10, DotDisp);
11025e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier    DotDispVal = DotDisp.getZExtValue();
1103ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier  } else if (Tok.is(AsmToken::Identifier)) {
1104ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier    // We should only see an identifier when parsing the original inline asm.
1105ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier    // The front-end should rewrite this in terms of immediates.
1106ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier    assert (isParsingInlineAsm() && "Unexpected field name!");
1107ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier
1108ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier    unsigned DotDisp;
1109ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier    std::pair<StringRef, StringRef> BaseMember = DotDispStr.split('.');
1110ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier    if (SemaCallback->LookupInlineAsmField(BaseMember.first, BaseMember.second,
1111ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier                                           DotDisp)) {
1112ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier      Err = "Unable to lookup field reference!";
1113ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier      return true;
1114ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier    }
1115ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier    DotDispVal = DotDisp;
11165e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier  } else {
11175e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier    Err = "Unexpected token type!";
11185e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier    return true;
11195e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier  }
112022f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier
1121ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier  if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) {
1122ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier    SMLoc Loc = SMLoc::getFromPointer(DotDispStr.data());
1123ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier    unsigned Len = DotDispStr.size();
1124ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier    unsigned Val = OrigDispVal + DotDispVal;
1125ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier    InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_DotOperator, Loc, Len,
1126ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier                                                Val));
112722f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier  }
11285e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier
11295e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier  *NewDisp = MCConstantExpr::Create(OrigDispVal + DotDispVal, getContext());
11305e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier  return false;
113122f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier}
113222f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier
1133c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier/// Parse the 'offset' operator.  This operator is used to specify the
1134c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier/// location rather then the content of a variable.
1135c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad RosierX86Operand *X86AsmParser::ParseIntelOffsetOfOperator(SMLoc Start) {
1136c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier  SMLoc OffsetOfLoc = Start;
1137c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier  Parser.Lex(); // Eat offset.
1138c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier  Start = Parser.getTok().getLoc();
1139c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier  assert (Parser.getTok().is(AsmToken::Identifier) && "Expected an identifier");
1140c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier
11416e43157b5d39a713d4061f97629bf9107c6d25e0Chad Rosier  SMLoc End;
1142c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier  const MCExpr *Val;
1143cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach  if (getParser().parseExpression(Val, End))
11447ab21c7a05509714358ac26530f5427de63113dfChad Rosier    return ErrorOperand(Start, "Unable to parse expression!");
1145c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier
11466e43157b5d39a713d4061f97629bf9107c6d25e0Chad Rosier  // Don't emit the offset operator.
11476e43157b5d39a713d4061f97629bf9107c6d25e0Chad Rosier  InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Skip, OffsetOfLoc, 7));
11486e43157b5d39a713d4061f97629bf9107c6d25e0Chad Rosier
1149c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier  // The offset operator will have an 'r' constraint, thus we need to create
1150c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier  // register operand to ensure proper matching.  Just pick a GPR based on
1151c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier  // the size of a pointer.
1152c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier  unsigned RegNo = is64BitMode() ? X86::RBX : X86::EBX;
1153c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier  return X86Operand::CreateReg(RegNo, Start, End, /*GetAddress=*/true,
1154c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier                               OffsetOfLoc);
1155d37ad247cc04c2a436e537767ac1aec709901594Devang Patel}
1156d37ad247cc04c2a436e537767ac1aec709901594Devang Patel
1157505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosierenum IntelOperatorKind {
1158505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier  IOK_LENGTH,
1159505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier  IOK_SIZE,
1160505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier  IOK_TYPE
1161505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier};
1162505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier
1163505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier/// Parse the 'LENGTH', 'TYPE' and 'SIZE' operators.  The LENGTH operator
1164505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier/// returns the number of elements in an array.  It returns the value 1 for
1165505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier/// non-array variables.  The SIZE operator returns the size of a C or C++
1166505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier/// variable.  A variable's size is the product of its LENGTH and TYPE.  The
1167505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier/// TYPE operator returns the size of a C or C++ type or variable. If the
1168505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier/// variable is an array, TYPE returns the size of a single element.
1169505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad RosierX86Operand *X86AsmParser::ParseIntelOperator(SMLoc Start, unsigned OpKind) {
1170efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier  SMLoc TypeLoc = Start;
1171efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier  Parser.Lex(); // Eat offset.
1172efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier  Start = Parser.getTok().getLoc();
1173efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier  assert (Parser.getTok().is(AsmToken::Identifier) && "Expected an identifier");
1174efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier
1175efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier  SMLoc End;
1176efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier  const MCExpr *Val;
1177cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach  if (getParser().parseExpression(Val, End))
1178efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier    return 0;
1179efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier
1180505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier  unsigned Length = 0, Size = 0, Type = 0;
1181efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier  if (const MCSymbolRefExpr *SymRef = dyn_cast<MCSymbolRefExpr>(Val)) {
1182efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier    const MCSymbol &Sym = SymRef->getSymbol();
1183efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier    // FIXME: The SemaLookup will fail if the name is anything other then an
1184efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier    // identifier.
1185efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier    // FIXME: Pass a valid SMLoc.
1186c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier    bool IsVarDecl;
1187505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier    if (!SemaCallback->LookupInlineAsmIdentifier(Sym.getName(), NULL, Length,
1188505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier                                                 Size, Type, IsVarDecl))
11893da67ca97383f8d305cc732019a51157f9fce290Chad Rosier      return ErrorOperand(Start, "Unable to lookup expr!");
1190505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier  }
1191505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier  unsigned CVal;
1192505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier  switch(OpKind) {
1193505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier  default: llvm_unreachable("Unexpected operand kind!");
1194505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier  case IOK_LENGTH: CVal = Length; break;
1195505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier  case IOK_SIZE: CVal = Size; break;
1196505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier  case IOK_TYPE: CVal = Type; break;
1197efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier  }
1198efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier
1199efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier  // Rewrite the type operator and the C or C++ type or variable in terms of an
1200efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier  // immediate.  E.g. TYPE foo -> $$4
1201efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier  unsigned Len = End.getPointer() - TypeLoc.getPointer();
1202505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier  InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Imm, TypeLoc, Len, CVal));
1203efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier
1204505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier  const MCExpr *Imm = MCConstantExpr::Create(CVal, getContext());
1205efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier  return X86Operand::CreateImm(Imm, Start, End, /*NeedAsmRewrite*/false);
1206efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier}
1207efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier
1208d37ad247cc04c2a436e537767ac1aec709901594Devang PatelX86Operand *X86AsmParser::ParseIntelOperand() {
1209d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  SMLoc Start = Parser.getTok().getLoc(), End;
12107ab21c7a05509714358ac26530f5427de63113dfChad Rosier  StringRef AsmTokStr = Parser.getTok().getString();
1211505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier
1212505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier  // Offset, length, type and size operators.
1213505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier  if (isParsingInlineAsm()) {
1214505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier    if (AsmTokStr == "offset" || AsmTokStr == "OFFSET")
1215505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier      return ParseIntelOffsetOfOperator(Start);
1216505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier    if (AsmTokStr == "length" || AsmTokStr == "LENGTH")
1217505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier      return ParseIntelOperator(Start, IOK_LENGTH);
1218505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier    if (AsmTokStr == "size" || AsmTokStr == "SIZE")
1219505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier      return ParseIntelOperator(Start, IOK_SIZE);
1220505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier    if (AsmTokStr == "type" || AsmTokStr == "TYPE")
1221505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier      return ParseIntelOperator(Start, IOK_TYPE);
1222505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier  }
1223505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier
1224505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier  // Immediate.
1225d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  if (getLexer().is(AsmToken::Integer) || getLexer().is(AsmToken::Real) ||
1226d37ad247cc04c2a436e537767ac1aec709901594Devang Patel      getLexer().is(AsmToken::Minus)) {
1227d37ad247cc04c2a436e537767ac1aec709901594Devang Patel    const MCExpr *Val;
1228cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    if (!getParser().parseExpression(Val, End)) {
1229d37ad247cc04c2a436e537767ac1aec709901594Devang Patel      return X86Operand::CreateImm(Val, Start, End);
1230d37ad247cc04c2a436e537767ac1aec709901594Devang Patel    }
1231d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  }
1232d37ad247cc04c2a436e537767ac1aec709901594Devang Patel
1233505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier  // Register.
12341aea430b8834f7bed3a14eda5027eac2133d6496Devang Patel  unsigned RegNo = 0;
12351aea430b8834f7bed3a14eda5027eac2133d6496Devang Patel  if (!ParseRegister(RegNo, Start, End)) {
12365b0f1b37639d57dec72972fe445880a8a99d8674Chad Rosier    // If this is a segment register followed by a ':', then this is the start
12375b0f1b37639d57dec72972fe445880a8a99d8674Chad Rosier    // of a memory reference, otherwise this is a normal register reference.
12385b0f1b37639d57dec72972fe445880a8a99d8674Chad Rosier    if (getLexer().isNot(AsmToken::Colon))
12393ebe59c892051375623fea55e977ff559fdb3323Jordan Rose      return X86Operand::CreateReg(RegNo, Start, End);
12405b0f1b37639d57dec72972fe445880a8a99d8674Chad Rosier
12415b0f1b37639d57dec72972fe445880a8a99d8674Chad Rosier    getParser().Lex(); // Eat the colon.
12425b0f1b37639d57dec72972fe445880a8a99d8674Chad Rosier    return ParseIntelMemOperand(RegNo, Start);
12430a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  }
12440a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel
1245505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier  // Memory operand.
12465b0f1b37639d57dec72972fe445880a8a99d8674Chad Rosier  return ParseIntelMemOperand(0, Start);
12470a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel}
12480a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel
1249dd929fc704054fa79cc1171354f95d91a5b62de2Devang PatelX86Operand *X86AsmParser::ParseATTOperand() {
125016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  switch (getLexer().getKind()) {
125116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  default:
1252eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    // Parse a memory operand with no segment register.
1253eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    return ParseMemOperand(0, Parser.getTok().getLoc());
125423075746a1418f281bc2a088ea85560bfd833599Chris Lattner  case AsmToken::Percent: {
1255eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    // Read the register.
125623075746a1418f281bc2a088ea85560bfd833599Chris Lattner    unsigned RegNo;
125729ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    SMLoc Start, End;
125829ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    if (ParseRegister(RegNo, Start, End)) return 0;
12593c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes    if (RegNo == X86::EIZ || RegNo == X86::RIZ) {
12605efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer      Error(Start, "%eiz and %riz can only be used as index registers",
12615efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer            SMRange(Start, End));
12623c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes      return 0;
12633c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes    }
1264f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
1265eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    // If this is a segment register followed by a ':', then this is the start
1266eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    // of a memory reference, otherwise this is a normal register reference.
1267eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    if (getLexer().isNot(AsmToken::Colon))
1268eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner      return X86Operand::CreateReg(RegNo, Start, End);
1269f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
1270f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
1271eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    getParser().Lex(); // Eat the colon.
1272eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    return ParseMemOperand(RegNo, Start);
127323075746a1418f281bc2a088ea85560bfd833599Chris Lattner  }
127416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  case AsmToken::Dollar: {
127516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // $42 -> immediate.
127618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    SMLoc Start = Parser.getTok().getLoc(), End;
1277b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
12788c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar    const MCExpr *Val;
1279cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    if (getParser().parseExpression(Val, End))
1280309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner      return 0;
1281b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner    return X86Operand::CreateImm(Val, Start, End);
128216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
128316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
128416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar}
128516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
1286eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner/// ParseMemOperand: segment: disp(basereg, indexreg, scale).  The '%ds:' prefix
1287eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner/// has already been parsed if present.
1288dd929fc704054fa79cc1171354f95d91a5b62de2Devang PatelX86Operand *X86AsmParser::ParseMemOperand(unsigned SegReg, SMLoc MemStart) {
1289f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
129016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  // We have to disambiguate a parenthesized expression "(4+5)" from the start
129116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)".  The
129275f265fbbbb64ab060bf41c5a4677ce56014ce9fChris Lattner  // only way to do this without lookahead is to eat the '(' and see what is
129375f265fbbbb64ab060bf41c5a4677ce56014ce9fChris Lattner  // after it.
12948c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar  const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext());
129516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  if (getLexer().isNot(AsmToken::LParen)) {
129654482b472a888c9efe003ad694ecf47b21878f0eChris Lattner    SMLoc ExprEnd;
1297cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    if (getParser().parseExpression(Disp, ExprEnd)) return 0;
1298f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
129916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // After parsing the base expression we could either have a parenthesized
130016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // memory address or not.  If not, return now.  If so, eat the (.
130116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    if (getLexer().isNot(AsmToken::LParen)) {
1302c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar      // Unless we have a segment register, treat this as an immediate.
1303309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner      if (SegReg == 0)
1304b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar        return X86Operand::CreateMem(Disp, MemStart, ExprEnd);
13050a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner      return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd);
130616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    }
1307f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
130816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // Eat the '('.
1309b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
131016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  } else {
131116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // Okay, we have a '('.  We don't know if this is an expression or not, but
131216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // so we have to eat the ( to see beyond it.
131318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    SMLoc LParenLoc = Parser.getTok().getLoc();
1314b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat the '('.
1315f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
13167b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby    if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) {
131716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // Nothing to do here, fall into the code below with the '(' part of the
131816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // memory operand consumed.
131916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    } else {
1320b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner      SMLoc ExprEnd;
1321f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
132216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // It must be an parenthesized expression, parse it now.
1323cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach      if (getParser().parseParenExpression(Disp, ExprEnd))
1324309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        return 0;
1325f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
132616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // After parsing the base expression we could either have a parenthesized
132716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // memory address or not.  If not, return now.  If so, eat the (.
132816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      if (getLexer().isNot(AsmToken::LParen)) {
1329c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar        // Unless we have a segment register, treat this as an immediate.
1330309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        if (SegReg == 0)
1331b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar          return X86Operand::CreateMem(Disp, LParenLoc, ExprEnd);
13320a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner        return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd);
133316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      }
1334f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
133516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // Eat the '('.
1336b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();
133716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    }
133816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
1339f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
134016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  // If we reached here, then we just ate the ( of the memory operand.  Process
134116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  // the rest of the memory operand.
1342022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
134384faf659125cb354794e457fa5a8a8daad84760dKevin Enderby  SMLoc IndexLoc;
1344f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
134529ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner  if (getLexer().is(AsmToken::Percent)) {
13465efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer    SMLoc StartLoc, EndLoc;
13475efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer    if (ParseRegister(BaseReg, StartLoc, EndLoc)) return 0;
13483c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes    if (BaseReg == X86::EIZ || BaseReg == X86::RIZ) {
13495efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer      Error(StartLoc, "eiz and riz can only be used as index registers",
13505efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer            SMRange(StartLoc, EndLoc));
13513c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes      return 0;
13523c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes    }
135329ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner  }
1354f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
135516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  if (getLexer().is(AsmToken::Comma)) {
1356b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat the comma.
135784faf659125cb354794e457fa5a8a8daad84760dKevin Enderby    IndexLoc = Parser.getTok().getLoc();
135816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
135916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // Following the comma we should have either an index register, or a scale
136016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // value. We don't support the later form, but we want to parse it
136116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // correctly.
136216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    //
136316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // Not that even though it would be completely consistent to support syntax
13643c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes    // like "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this.
13657b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby    if (getLexer().is(AsmToken::Percent)) {
136629ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner      SMLoc L;
136729ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner      if (ParseRegister(IndexReg, L, L)) return 0;
1368f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
136916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      if (getLexer().isNot(AsmToken::RParen)) {
137016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar        // Parse the scale amount:
137116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar        //  ::= ',' [scale-expression]
1372309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        if (getLexer().isNot(AsmToken::Comma)) {
137318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan          Error(Parser.getTok().getLoc(),
1374309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner                "expected comma in scale expression");
1375309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner          return 0;
1376309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        }
1377b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan        Parser.Lex(); // Eat the comma.
137816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
137916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar        if (getLexer().isNot(AsmToken::RParen)) {
138018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan          SMLoc Loc = Parser.getTok().getLoc();
138116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
138216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar          int64_t ScaleVal;
1383cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach          if (getParser().parseAbsoluteExpression(ScaleVal)){
138458dfaa14651f36fc9fce2031eb011e65ae267b9fKevin Enderby            Error(Loc, "expected scale expression");
1385309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner            return 0;
138676bd9386f1e1487a49c7c34ff95078dea20e3154Craig Topper          }
1387f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
138816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar          // Validate the scale amount.
1389309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner          if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8){
1390309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner            Error(Loc, "scale factor in address must be 1, 2, 4 or 8");
1391309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner            return 0;
1392309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner          }
139316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar          Scale = (unsigned)ScaleVal;
139416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar        }
139516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      }
139616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    } else if (getLexer().isNot(AsmToken::RParen)) {
1397ee9102587e7f6fc95de9fc5731b341eeb9bfc3caDaniel Dunbar      // A scale amount without an index is ignored.
139816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // index.
139918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan      SMLoc Loc = Parser.getTok().getLoc();
140016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
140116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      int64_t Value;
1402cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach      if (getParser().parseAbsoluteExpression(Value))
1403309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        return 0;
1404f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
1405ee9102587e7f6fc95de9fc5731b341eeb9bfc3caDaniel Dunbar      if (Value != 1)
1406ee9102587e7f6fc95de9fc5731b341eeb9bfc3caDaniel Dunbar        Warning(Loc, "scale factor without index register is ignored");
1407ee9102587e7f6fc95de9fc5731b341eeb9bfc3caDaniel Dunbar      Scale = 1;
140816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    }
140916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
1410f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
141116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  // Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
1412309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner  if (getLexer().isNot(AsmToken::RParen)) {
141318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    Error(Parser.getTok().getLoc(), "unexpected token in memory operand");
1414309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner    return 0;
1415309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner  }
14163ebe59c892051375623fea55e977ff559fdb3323Jordan Rose  SMLoc MemEnd = Parser.getTok().getEndLoc();
1417b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat the ')'.
1418f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
141984faf659125cb354794e457fa5a8a8daad84760dKevin Enderby  // If we have both a base register and an index register make sure they are
142084faf659125cb354794e457fa5a8a8daad84760dKevin Enderby  // both 64-bit or 32-bit registers.
14211f7a1b68a07ea6bdf521525a7928f4a8c5216713Manman Ren  // To support VSIB, IndexReg can be 128-bit or 256-bit registers.
142284faf659125cb354794e457fa5a8a8daad84760dKevin Enderby  if (BaseReg != 0 && IndexReg != 0) {
142384faf659125cb354794e457fa5a8a8daad84760dKevin Enderby    if (X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) &&
14241f7a1b68a07ea6bdf521525a7928f4a8c5216713Manman Ren        (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
14251f7a1b68a07ea6bdf521525a7928f4a8c5216713Manman Ren         X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg)) &&
142684faf659125cb354794e457fa5a8a8daad84760dKevin Enderby        IndexReg != X86::RIZ) {
142784faf659125cb354794e457fa5a8a8daad84760dKevin Enderby      Error(IndexLoc, "index register is 32-bit, but base register is 64-bit");
142884faf659125cb354794e457fa5a8a8daad84760dKevin Enderby      return 0;
142984faf659125cb354794e457fa5a8a8daad84760dKevin Enderby    }
143084faf659125cb354794e457fa5a8a8daad84760dKevin Enderby    if (X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg) &&
14311f7a1b68a07ea6bdf521525a7928f4a8c5216713Manman Ren        (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
14321f7a1b68a07ea6bdf521525a7928f4a8c5216713Manman Ren         X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) &&
143384faf659125cb354794e457fa5a8a8daad84760dKevin Enderby        IndexReg != X86::EIZ){
143484faf659125cb354794e457fa5a8a8daad84760dKevin Enderby      Error(IndexLoc, "index register is 64-bit, but base register is 32-bit");
143584faf659125cb354794e457fa5a8a8daad84760dKevin Enderby      return 0;
143684faf659125cb354794e457fa5a8a8daad84760dKevin Enderby    }
143784faf659125cb354794e457fa5a8a8daad84760dKevin Enderby  }
143884faf659125cb354794e457fa5a8a8daad84760dKevin Enderby
14390a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner  return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale,
14400a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner                               MemStart, MemEnd);
1441dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar}
1442dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar
1443dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patelbool X86AsmParser::
14446a020a71173a3ea7738a9df69982e85ddbfe0303Chad RosierParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
14459898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner                 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
14466a020a71173a3ea7738a9df69982e85ddbfe0303Chad Rosier  InstInfo = &Info;
1447693173feefaa326fad0e386470846fb3199ba381Chris Lattner  StringRef PatchedName = Name;
144839e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar
1449d8f717911dcdccb1a60b3049ea22c7767970dcb7Chris Lattner  // FIXME: Hack to recognize setneb as setne.
1450d8f717911dcdccb1a60b3049ea22c7767970dcb7Chris Lattner  if (PatchedName.startswith("set") && PatchedName.endswith("b") &&
1451d8f717911dcdccb1a60b3049ea22c7767970dcb7Chris Lattner      PatchedName != "setb" && PatchedName != "setnb")
1452d8f717911dcdccb1a60b3049ea22c7767970dcb7Chris Lattner    PatchedName = PatchedName.substr(0, Name.size()-1);
145336b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier
145439e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar  // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}.
145539e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar  const MCExpr *ExtraImmOp = 0;
1456428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes  if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) &&
145739e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      (PatchedName.endswith("ss") || PatchedName.endswith("sd") ||
145839e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar       PatchedName.endswith("ps") || PatchedName.endswith("pd"))) {
14599e6ddcb88ec40422c0ebd260567e2264ec424506Craig Topper    bool IsVCMP = PatchedName[0] == 'v';
1460428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes    unsigned SSECCIdx = IsVCMP ? 4 : 3;
146139e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar    unsigned SSEComparisonCode = StringSwitch<unsigned>(
1462428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes      PatchedName.slice(SSECCIdx, PatchedName.size() - 2))
14639e6ddcb88ec40422c0ebd260567e2264ec424506Craig Topper      .Case("eq",       0x00)
14649e6ddcb88ec40422c0ebd260567e2264ec424506Craig Topper      .Case("lt",       0x01)
14659e6ddcb88ec40422c0ebd260567e2264ec424506Craig Topper      .Case("le",       0x02)
14669e6ddcb88ec40422c0ebd260567e2264ec424506Craig Topper      .Case("unord",    0x03)
14679e6ddcb88ec40422c0ebd260567e2264ec424506Craig Topper      .Case("neq",      0x04)
14689e6ddcb88ec40422c0ebd260567e2264ec424506Craig Topper      .Case("nlt",      0x05)
14699e6ddcb88ec40422c0ebd260567e2264ec424506Craig Topper      .Case("nle",      0x06)
14709e6ddcb88ec40422c0ebd260567e2264ec424506Craig Topper      .Case("ord",      0x07)
14719e6ddcb88ec40422c0ebd260567e2264ec424506Craig Topper      /* AVX only from here */
14729e6ddcb88ec40422c0ebd260567e2264ec424506Craig Topper      .Case("eq_uq",    0x08)
14739e6ddcb88ec40422c0ebd260567e2264ec424506Craig Topper      .Case("nge",      0x09)
1474cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("ngt",      0x0A)
1475cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("false",    0x0B)
1476cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("neq_oq",   0x0C)
1477cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("ge",       0x0D)
1478cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("gt",       0x0E)
1479cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("true",     0x0F)
1480cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("eq_os",    0x10)
1481cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("lt_oq",    0x11)
1482cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("le_oq",    0x12)
1483cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("unord_s",  0x13)
1484cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("neq_us",   0x14)
1485cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("nlt_uq",   0x15)
1486cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("nle_uq",   0x16)
1487cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("ord_s",    0x17)
1488cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("eq_us",    0x18)
1489cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("nge_uq",   0x19)
1490cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("ngt_uq",   0x1A)
1491cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("false_os", 0x1B)
1492cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("neq_os",   0x1C)
1493cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("ge_oq",    0x1D)
1494cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("gt_oq",    0x1E)
1495cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("true_us",  0x1F)
149639e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      .Default(~0U);
14979e6ddcb88ec40422c0ebd260567e2264ec424506Craig Topper    if (SSEComparisonCode != ~0U && (IsVCMP || SSEComparisonCode < 8)) {
149839e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      ExtraImmOp = MCConstantExpr::Create(SSEComparisonCode,
149939e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar                                          getParser().getContext());
150039e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      if (PatchedName.endswith("ss")) {
1501428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes        PatchedName = IsVCMP ? "vcmpss" : "cmpss";
150239e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      } else if (PatchedName.endswith("sd")) {
1503428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes        PatchedName = IsVCMP ? "vcmpsd" : "cmpsd";
150439e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      } else if (PatchedName.endswith("ps")) {
1505428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes        PatchedName = IsVCMP ? "vcmpps" : "cmpps";
150639e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      } else {
150739e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar        assert(PatchedName.endswith("pd") && "Unexpected mnemonic!");
1508428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes        PatchedName = IsVCMP ? "vcmppd" : "cmppd";
150939e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      }
151039e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar    }
151139e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar  }
1512f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes
15131b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar  Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
151416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
1515885f65b4a1c1ec80cd800a0617c57a2289472165Devang Patel  if (ExtraImmOp && !isParsingIntelSyntax())
151639e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar    Operands.push_back(X86Operand::CreateImm(ExtraImmOp, NameLoc, NameLoc));
1517c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
15182544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  // Determine whether this is an instruction prefix.
15192544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  bool isPrefix =
1520693173feefaa326fad0e386470846fb3199ba381Chris Lattner    Name == "lock" || Name == "rep" ||
1521693173feefaa326fad0e386470846fb3199ba381Chris Lattner    Name == "repe" || Name == "repz" ||
1522beb6898df8f96ccea4ae147587479b507bb3e491Rafael Espindola    Name == "repne" || Name == "repnz" ||
1523bfd2d26159c87262fcf462ea442f99478a2093c9Rafael Espindola    Name == "rex64" || Name == "data16";
1524c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
1525c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
15262544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  // This does the actual operand parsing.  Don't parse any more if we have a
15272544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we
15282544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  // just want to parse the "lock" as the first instruction and the "incl" as
15292544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  // the next one.
15302544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  if (getLexer().isNot(AsmToken::EndOfStatement) && !isPrefix) {
15310db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar
15320db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar    // Parse '*' modifier.
15330db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar    if (getLexer().is(AsmToken::Star)) {
153418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan      SMLoc Loc = Parser.getTok().getLoc();
1535b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner      Operands.push_back(X86Operand::CreateToken("*", Loc));
1536b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex(); // Eat the star.
15370db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar    }
15380db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar
153916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // Read the first operand.
1540309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner    if (X86Operand *Op = ParseOperand())
1541309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner      Operands.push_back(Op);
1542cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    else {
1543cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach      Parser.eatToEndOfStatement();
154416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      return true;
1545cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    }
154639e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar
154716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    while (getLexer().is(AsmToken::Comma)) {
1548b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();  // Eat the comma.
154916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
155016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // Parse and remember the operand.
1551309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner      if (X86Operand *Op = ParseOperand())
1552309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        Operands.push_back(Op);
1553cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      else {
1554cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach        Parser.eatToEndOfStatement();
155516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar        return true;
1556cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      }
155716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    }
1558c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
1559cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    if (getLexer().isNot(AsmToken::EndOfStatement)) {
1560c146c4d47a7ec54c14e730c30bea821c34dc4c48Chris Lattner      SMLoc Loc = getLexer().getLoc();
1561cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach      Parser.eatToEndOfStatement();
1562c146c4d47a7ec54c14e730c30bea821c34dc4c48Chris Lattner      return Error(Loc, "unexpected token in argument list");
1563cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    }
156416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
1565c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
15662544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  if (getLexer().is(AsmToken::EndOfStatement))
15672544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner    Parser.Lex(); // Consume the EndOfStatement
156876331754d4a06e2394c15ae8f4870f4aeaf5ca1fKevin Enderby  else if (isPrefix && getLexer().is(AsmToken::Slash))
156976331754d4a06e2394c15ae8f4870f4aeaf5ca1fKevin Enderby    Parser.Lex(); // Consume the prefix separator Slash
157016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
1571885f65b4a1c1ec80cd800a0617c57a2289472165Devang Patel  if (ExtraImmOp && isParsingIntelSyntax())
1572885f65b4a1c1ec80cd800a0617c57a2289472165Devang Patel    Operands.push_back(X86Operand::CreateImm(ExtraImmOp, NameLoc, NameLoc));
1573885f65b4a1c1ec80cd800a0617c57a2289472165Devang Patel
157498c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner  // This is a terrible hack to handle "out[bwl]? %al, (%dx)" ->
157598c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner  // "outb %al, %dx".  Out doesn't take a memory form, but this is a widely
157698c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner  // documented form in various unofficial manuals, so a lot of code uses it.
157798c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner  if ((Name == "outb" || Name == "outw" || Name == "outl" || Name == "out") &&
157898c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      Operands.size() == 3) {
157998c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner    X86Operand &Op = *(X86Operand*)Operands.back();
158098c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner    if (Op.isMem() && Op.Mem.SegReg == 0 &&
158198c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner        isa<MCConstantExpr>(Op.Mem.Disp) &&
158298c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner        cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
158398c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner        Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
158498c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      SMLoc Loc = Op.getEndLoc();
158598c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      Operands.back() = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
158698c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      delete &Op;
158798c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner    }
158898c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner  }
158900743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger  // Same hack for "in[bwl]? (%dx), %al" -> "inb %dx, %al".
159000743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger  if ((Name == "inb" || Name == "inw" || Name == "inl" || Name == "in") &&
159100743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger      Operands.size() == 3) {
159200743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger    X86Operand &Op = *(X86Operand*)Operands.begin()[1];
159300743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger    if (Op.isMem() && Op.Mem.SegReg == 0 &&
159400743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger        isa<MCConstantExpr>(Op.Mem.Disp) &&
159500743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger        cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
159600743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger        Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
159700743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger      SMLoc Loc = Op.getEndLoc();
159800743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger      Operands.begin()[1] = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
159900743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger      delete &Op;
160000743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger    }
160100743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger  }
160296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  // Transform "ins[bwl] %dx, %es:(%edi)" into "ins[bwl]"
160396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  if (Name.startswith("ins") && Operands.size() == 3 &&
160496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      (Name == "insb" || Name == "insw" || Name == "insl")) {
160596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand &Op = *(X86Operand*)Operands.begin()[1];
160696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand &Op2 = *(X86Operand*)Operands.begin()[2];
160796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    if (Op.isReg() && Op.getReg() == X86::DX && isDstOp(Op2)) {
160896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      Operands.pop_back();
160996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      Operands.pop_back();
161096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      delete &Op;
161196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      delete &Op2;
161296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    }
161396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  }
161496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger
161596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  // Transform "outs[bwl] %ds:(%esi), %dx" into "out[bwl]"
161696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  if (Name.startswith("outs") && Operands.size() == 3 &&
161796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      (Name == "outsb" || Name == "outsw" || Name == "outsl")) {
161896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand &Op = *(X86Operand*)Operands.begin()[1];
161996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand &Op2 = *(X86Operand*)Operands.begin()[2];
162096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    if (isSrcOp(Op) && Op2.isReg() && Op2.getReg() == X86::DX) {
162196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      Operands.pop_back();
162296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      Operands.pop_back();
162396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      delete &Op;
162496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      delete &Op2;
162596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    }
162696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  }
162796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger
162896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  // Transform "movs[bwl] %ds:(%esi), %es:(%edi)" into "movs[bwl]"
162996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  if (Name.startswith("movs") && Operands.size() == 3 &&
163096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      (Name == "movsb" || Name == "movsw" || Name == "movsl" ||
163159ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng       (is64BitMode() && Name == "movsq"))) {
163296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand &Op = *(X86Operand*)Operands.begin()[1];
163396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand &Op2 = *(X86Operand*)Operands.begin()[2];
163496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    if (isSrcOp(Op) && isDstOp(Op2)) {
163596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      Operands.pop_back();
163696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      Operands.pop_back();
163796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      delete &Op;
163896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      delete &Op2;
163996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    }
164096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  }
164196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  // Transform "lods[bwl] %ds:(%esi),{%al,%ax,%eax,%rax}" into "lods[bwl]"
164296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  if (Name.startswith("lods") && Operands.size() == 3 &&
164396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      (Name == "lods" || Name == "lodsb" || Name == "lodsw" ||
164459ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng       Name == "lodsl" || (is64BitMode() && Name == "lodsq"))) {
164596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]);
164696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand *Op2 = static_cast<X86Operand*>(Operands[2]);
164796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    if (isSrcOp(*Op1) && Op2->isReg()) {
164896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      const char *ins;
164996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      unsigned reg = Op2->getReg();
165096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      bool isLods = Name == "lods";
165196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      if (reg == X86::AL && (isLods || Name == "lodsb"))
165296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = "lodsb";
165396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      else if (reg == X86::AX && (isLods || Name == "lodsw"))
165496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = "lodsw";
165596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      else if (reg == X86::EAX && (isLods || Name == "lodsl"))
165696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = "lodsl";
165796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      else if (reg == X86::RAX && (isLods || Name == "lodsq"))
165896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = "lodsq";
165996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      else
166096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = NULL;
166196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      if (ins != NULL) {
166296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        Operands.pop_back();
166396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        Operands.pop_back();
166496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        delete Op1;
166596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        delete Op2;
166696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        if (Name != ins)
166796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger          static_cast<X86Operand*>(Operands[0])->setTokenValue(ins);
166896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      }
166996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    }
167096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  }
167196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  // Transform "stos[bwl] {%al,%ax,%eax,%rax},%es:(%edi)" into "stos[bwl]"
167296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  if (Name.startswith("stos") && Operands.size() == 3 &&
167396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      (Name == "stos" || Name == "stosb" || Name == "stosw" ||
167459ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng       Name == "stosl" || (is64BitMode() && Name == "stosq"))) {
167596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]);
167696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand *Op2 = static_cast<X86Operand*>(Operands[2]);
167796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    if (isDstOp(*Op2) && Op1->isReg()) {
167896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      const char *ins;
167996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      unsigned reg = Op1->getReg();
168096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      bool isStos = Name == "stos";
168196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      if (reg == X86::AL && (isStos || Name == "stosb"))
168296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = "stosb";
168396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      else if (reg == X86::AX && (isStos || Name == "stosw"))
168496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = "stosw";
168596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      else if (reg == X86::EAX && (isStos || Name == "stosl"))
168696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = "stosl";
168796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      else if (reg == X86::RAX && (isStos || Name == "stosq"))
168896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = "stosq";
168996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      else
169096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = NULL;
169196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      if (ins != NULL) {
169296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        Operands.pop_back();
169396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        Operands.pop_back();
169496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        delete Op1;
169596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        delete Op2;
169696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        if (Name != ins)
169796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger          static_cast<X86Operand*>(Operands[0])->setTokenValue(ins);
169896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      }
169996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    }
170096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  }
170196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger
1702e9e16a36d9ff355dab60e4b95673bf7a0cd27e86Chris Lattner  // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>.  Canonicalize to
1703ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner  // "shift <op>".
1704d5e7705a05947e60806b795880f09757e835f590Daniel Dunbar  if ((Name.startswith("shr") || Name.startswith("sar") ||
17058c24b0c6996a8f03ff32766f0695dcf19577af59Chris Lattner       Name.startswith("shl") || Name.startswith("sal") ||
17068c24b0c6996a8f03ff32766f0695dcf19577af59Chris Lattner       Name.startswith("rcl") || Name.startswith("rcr") ||
17078c24b0c6996a8f03ff32766f0695dcf19577af59Chris Lattner       Name.startswith("rol") || Name.startswith("ror")) &&
170847ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner      Operands.size() == 3) {
1709be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel    if (isParsingIntelSyntax()) {
17103b96e1fe3b695e6d845668ea90d75016f0f46a17Devang Patel      // Intel syntax
17113b96e1fe3b695e6d845668ea90d75016f0f46a17Devang Patel      X86Operand *Op1 = static_cast<X86Operand*>(Operands[2]);
17123b96e1fe3b695e6d845668ea90d75016f0f46a17Devang Patel      if (Op1->isImm() && isa<MCConstantExpr>(Op1->getImm()) &&
171376bd9386f1e1487a49c7c34ff95078dea20e3154Craig Topper          cast<MCConstantExpr>(Op1->getImm())->getValue() == 1) {
171476bd9386f1e1487a49c7c34ff95078dea20e3154Craig Topper        delete Operands[2];
171576bd9386f1e1487a49c7c34ff95078dea20e3154Craig Topper        Operands.pop_back();
17163b96e1fe3b695e6d845668ea90d75016f0f46a17Devang Patel      }
17173b96e1fe3b695e6d845668ea90d75016f0f46a17Devang Patel    } else {
17183b96e1fe3b695e6d845668ea90d75016f0f46a17Devang Patel      X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]);
17193b96e1fe3b695e6d845668ea90d75016f0f46a17Devang Patel      if (Op1->isImm() && isa<MCConstantExpr>(Op1->getImm()) &&
172076bd9386f1e1487a49c7c34ff95078dea20e3154Craig Topper          cast<MCConstantExpr>(Op1->getImm())->getValue() == 1) {
172176bd9386f1e1487a49c7c34ff95078dea20e3154Craig Topper        delete Operands[1];
172276bd9386f1e1487a49c7c34ff95078dea20e3154Craig Topper        Operands.erase(Operands.begin() + 1);
17233b96e1fe3b695e6d845668ea90d75016f0f46a17Devang Patel      }
172447ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner    }
1725f2de13f8d7bed958538bbd9dbeb9b15ea48456ccDaniel Dunbar  }
172636b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier
172715f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner  // Transforms "int $3" into "int3" as a size optimization.  We can't write an
172815f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner  // instalias with an immediate operand yet.
172915f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner  if (Name == "int" && Operands.size() == 2) {
173015f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner    X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]);
173115f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner    if (Op1->isImm() && isa<MCConstantExpr>(Op1->getImm()) &&
173215f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner        cast<MCConstantExpr>(Op1->getImm())->getValue() == 3) {
173315f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner      delete Operands[1];
173415f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner      Operands.erase(Operands.begin() + 1);
173515f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner      static_cast<X86Operand*>(Operands[0])->setTokenValue("int3");
173615f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner    }
173715f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner  }
1738c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
17399898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner  return false;
1740a3af370dc12f6d5100da5d614ab0a62da135569aDaniel Dunbar}
1741a3af370dc12f6d5100da5d614ab0a62da135569aDaniel Dunbar
17424bef961baf9660f1ac5a5b80378631cd942636b2Craig Topperstatic bool convertToSExti8(MCInst &Inst, unsigned Opcode, unsigned Reg,
17434bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper                            bool isCmp) {
17444bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper  MCInst TmpInst;
17454bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper  TmpInst.setOpcode(Opcode);
17464bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper  if (!isCmp)
17474bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper    TmpInst.addOperand(MCOperand::CreateReg(Reg));
17484bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper  TmpInst.addOperand(MCOperand::CreateReg(Reg));
17494bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper  TmpInst.addOperand(Inst.getOperand(0));
17504bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper  Inst = TmpInst;
17514bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper  return true;
17524bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper}
1753ac0f0486022fb1798579c9a550154e839770efa9Devang Patel
17544bef961baf9660f1ac5a5b80378631cd942636b2Craig Topperstatic bool convert16i16to16ri8(MCInst &Inst, unsigned Opcode,
17554bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper                                bool isCmp = false) {
17564bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper  if (!Inst.getOperand(0).isImm() ||
17574bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper      !isImmSExti16i8Value(Inst.getOperand(0).getImm()))
17584bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper    return false;
1759a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel
17604bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper  return convertToSExti8(Inst, Opcode, X86::AX, isCmp);
17614bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper}
1762a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel
17634bef961baf9660f1ac5a5b80378631cd942636b2Craig Topperstatic bool convert32i32to32ri8(MCInst &Inst, unsigned Opcode,
17644bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper                                bool isCmp = false) {
17654bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper  if (!Inst.getOperand(0).isImm() ||
17664bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper      !isImmSExti32i8Value(Inst.getOperand(0).getImm()))
17674bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper    return false;
1768a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel
17694bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper  return convertToSExti8(Inst, Opcode, X86::EAX, isCmp);
17704bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper}
1771a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel
17724bef961baf9660f1ac5a5b80378631cd942636b2Craig Topperstatic bool convert64i32to64ri8(MCInst &Inst, unsigned Opcode,
17734bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper                                bool isCmp = false) {
17744bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper  if (!Inst.getOperand(0).isImm() ||
17754bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper      !isImmSExti64i8Value(Inst.getOperand(0).getImm()))
17764bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper    return false;
1777a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel
17784bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper  return convertToSExti8(Inst, Opcode, X86::RAX, isCmp);
17794bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper}
1780a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel
17814bef961baf9660f1ac5a5b80378631cd942636b2Craig Topperbool X86AsmParser::
17824bef961baf9660f1ac5a5b80378631cd942636b2Craig TopperprocessInstruction(MCInst &Inst,
17834bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper                   const SmallVectorImpl<MCParsedAsmOperand*> &Ops) {
17844bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper  switch (Inst.getOpcode()) {
17854bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper  default: return false;
17864bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper  case X86::AND16i16: return convert16i16to16ri8(Inst, X86::AND16ri8);
17874bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper  case X86::AND32i32: return convert32i32to32ri8(Inst, X86::AND32ri8);
17884bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper  case X86::AND64i32: return convert64i32to64ri8(Inst, X86::AND64ri8);
17894bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper  case X86::XOR16i16: return convert16i16to16ri8(Inst, X86::XOR16ri8);
17904bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper  case X86::XOR32i32: return convert32i32to32ri8(Inst, X86::XOR32ri8);
17914bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper  case X86::XOR64i32: return convert64i32to64ri8(Inst, X86::XOR64ri8);
17924bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper  case X86::OR16i16:  return convert16i16to16ri8(Inst, X86::OR16ri8);
17934bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper  case X86::OR32i32:  return convert32i32to32ri8(Inst, X86::OR32ri8);
17944bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper  case X86::OR64i32:  return convert64i32to64ri8(Inst, X86::OR64ri8);
17954bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper  case X86::CMP16i16: return convert16i16to16ri8(Inst, X86::CMP16ri8, true);
17964bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper  case X86::CMP32i32: return convert32i32to32ri8(Inst, X86::CMP32ri8, true);
17974bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper  case X86::CMP64i32: return convert64i32to64ri8(Inst, X86::CMP64ri8, true);
17984bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper  case X86::ADD16i16: return convert16i16to16ri8(Inst, X86::ADD16ri8);
17994bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper  case X86::ADD32i32: return convert32i32to32ri8(Inst, X86::ADD32ri8);
18004bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper  case X86::ADD64i32: return convert64i32to64ri8(Inst, X86::ADD64ri8);
18014bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper  case X86::SUB16i16: return convert16i16to16ri8(Inst, X86::SUB16ri8);
18024bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper  case X86::SUB32i32: return convert32i32to32ri8(Inst, X86::SUB32ri8);
18034bef961baf9660f1ac5a5b80378631cd942636b2Craig Topper  case X86::SUB64i32: return convert64i32to64ri8(Inst, X86::SUB64ri8);
18048ee1c1cfaff9eece05ecabfa267cd68c98af5dd2Craig Topper  case X86::ADC16i16: return convert16i16to16ri8(Inst, X86::ADC16ri8);
18058ee1c1cfaff9eece05ecabfa267cd68c98af5dd2Craig Topper  case X86::ADC32i32: return convert32i32to32ri8(Inst, X86::ADC32ri8);
18068ee1c1cfaff9eece05ecabfa267cd68c98af5dd2Craig Topper  case X86::ADC64i32: return convert64i32to64ri8(Inst, X86::ADC64ri8);
18078ee1c1cfaff9eece05ecabfa267cd68c98af5dd2Craig Topper  case X86::SBB16i16: return convert16i16to16ri8(Inst, X86::SBB16ri8);
18088ee1c1cfaff9eece05ecabfa267cd68c98af5dd2Craig Topper  case X86::SBB32i32: return convert32i32to32ri8(Inst, X86::SBB32ri8);
18098ee1c1cfaff9eece05ecabfa267cd68c98af5dd2Craig Topper  case X86::SBB64i32: return convert64i32to64ri8(Inst, X86::SBB64ri8);
1810b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel  }
1811b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel}
1812b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel
18133ca6382120c16e30151e19175d40480ee72de641Jim Grosbachstatic const char *getSubtargetFeatureName(unsigned Val);
1814b8ba13f0096b560ee618512019ca86969a9fa772Devang Patelbool X86AsmParser::
181584125ca43c758fd21fdab2b05196e0df57c55c96Chad RosierMatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
18167c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner                        SmallVectorImpl<MCParsedAsmOperand*> &Operands,
181784125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier                        MCStreamer &Out, unsigned &ErrorInfo,
181884125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier                        bool MatchingInlineAsm) {
1819f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar  assert(!Operands.empty() && "Unexpect empty operand list!");
18207c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner  X86Operand *Op = static_cast<X86Operand*>(Operands[0]);
18217c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner  assert(Op->isToken() && "Leading operand should always be a mnemonic!");
1822b4fdadef51ed254d9282356463c6b11ff8a102dfChad Rosier  ArrayRef<SMRange> EmptyRanges = ArrayRef<SMRange>();
18237c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner
18247c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner  // First, handle aliases that expand to multiple instructions.
18257c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner  // FIXME: This should be replaced with a real .td file alias mechanism.
18264ee0808d9f1c7d64b0b304e610ce0fb496dd3279Chad Rosier  // Also, MatchInstructionImpl should actually *do* the EmitInstruction
182790fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner  // call.
18280966ec08610c02c8556105f2fff88a7e7247a549Andrew Trick  if (Op->getToken() == "fstsw" || Op->getToken() == "fstcw" ||
18298b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner      Op->getToken() == "fstsww" || Op->getToken() == "fstcww" ||
1830905f2e06691672c236ae864faf0ad7220afc2844Chris Lattner      Op->getToken() == "finit" || Op->getToken() == "fsave" ||
18315a378076a44ef3f507b91aa8e7715fabaec42074Kevin Enderby      Op->getToken() == "fstenv" || Op->getToken() == "fclex") {
18327c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner    MCInst Inst;
18337c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner    Inst.setOpcode(X86::WAIT);
1834cb5dca38157a48c734660746e7f7340d5db7c2dbJim Grosbach    Inst.setLoc(IDLoc);
18357a2b624bb34374fe233f71cc5220d5ae0a0971cfChad Rosier    if (!MatchingInlineAsm)
183622685876ed7231f32f7d1698c00acab22825b74cChad Rosier      Out.EmitInstruction(Inst);
1837f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar
18380bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner    const char *Repl =
18390bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner      StringSwitch<const char*>(Op->getToken())
18408b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner        .Case("finit",  "fninit")
18418b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner        .Case("fsave",  "fnsave")
18428b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner        .Case("fstcw",  "fnstcw")
18438b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner        .Case("fstcww",  "fnstcw")
1844905f2e06691672c236ae864faf0ad7220afc2844Chris Lattner        .Case("fstenv", "fnstenv")
18458b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner        .Case("fstsw",  "fnstsw")
18468b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner        .Case("fstsww", "fnstsw")
18478b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner        .Case("fclex",  "fnclex")
18480bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner        .Default(0);
18490bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner    assert(Repl && "Unknown wait-prefixed instruction");
1850b0f96facd6e6637cb71bbeaf2f4e006f0b6348e3Benjamin Kramer    delete Operands[0];
18510bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner    Operands[0] = X86Operand::CreateToken(Repl, IDLoc);
18527c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner  }
1853c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
1854a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  bool WasOriginallyInvalidOperand = false;
18557036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner  MCInst Inst;
1856c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
1857c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // First, try a direct match.
18586e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier  switch (MatchInstructionImpl(Operands, Inst,
185984125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier                               ErrorInfo, MatchingInlineAsm,
1860be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel                               isParsingIntelSyntax())) {
186119cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  default: break;
1862ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  case Match_Success:
1863b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    // Some instructions need post-processing to, for example, tweak which
1864b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    // encoding is selected. Loop on it while changes happen so the
186536b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier    // individual transformations can chain off each other.
18667a2b624bb34374fe233f71cc5220d5ae0a0971cfChad Rosier    if (!MatchingInlineAsm)
186722685876ed7231f32f7d1698c00acab22825b74cChad Rosier      while (processInstruction(Inst, Operands))
186822685876ed7231f32f7d1698c00acab22825b74cChad Rosier        ;
1869b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel
1870cb5dca38157a48c734660746e7f7340d5db7c2dbJim Grosbach    Inst.setLoc(IDLoc);
18717a2b624bb34374fe233f71cc5220d5ae0a0971cfChad Rosier    if (!MatchingInlineAsm)
187222685876ed7231f32f7d1698c00acab22825b74cChad Rosier      Out.EmitInstruction(Inst);
187322685876ed7231f32f7d1698c00acab22825b74cChad Rosier    Opcode = Inst.getOpcode();
1874c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar    return false;
18753ca6382120c16e30151e19175d40480ee72de641Jim Grosbach  case Match_MissingFeature: {
18763ca6382120c16e30151e19175d40480ee72de641Jim Grosbach    assert(ErrorInfo && "Unknown missing feature!");
18773ca6382120c16e30151e19175d40480ee72de641Jim Grosbach    // Special case the error message for the very common case where only
18783ca6382120c16e30151e19175d40480ee72de641Jim Grosbach    // a single subtarget feature is missing.
18793ca6382120c16e30151e19175d40480ee72de641Jim Grosbach    std::string Msg = "instruction requires:";
18803ca6382120c16e30151e19175d40480ee72de641Jim Grosbach    unsigned Mask = 1;
18813ca6382120c16e30151e19175d40480ee72de641Jim Grosbach    for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
18823ca6382120c16e30151e19175d40480ee72de641Jim Grosbach      if (ErrorInfo & Mask) {
18833ca6382120c16e30151e19175d40480ee72de641Jim Grosbach        Msg += " ";
18843ca6382120c16e30151e19175d40480ee72de641Jim Grosbach        Msg += getSubtargetFeatureName(ErrorInfo & Mask);
18853ca6382120c16e30151e19175d40480ee72de641Jim Grosbach      }
18863ca6382120c16e30151e19175d40480ee72de641Jim Grosbach      Mask <<= 1;
18873ca6382120c16e30151e19175d40480ee72de641Jim Grosbach    }
18883ca6382120c16e30151e19175d40480ee72de641Jim Grosbach    return Error(IDLoc, Msg, EmptyRanges, MatchingInlineAsm);
18893ca6382120c16e30151e19175d40480ee72de641Jim Grosbach  }
1890a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  case Match_InvalidOperand:
1891a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner    WasOriginallyInvalidOperand = true;
1892a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner    break;
1893a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  case Match_MnemonicFail:
1894ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    break;
1895ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  }
1896c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
1897c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // FIXME: Ideally, we would only attempt suffix matches for things which are
1898c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // valid prefixes, and we could just infer the right unambiguous
1899c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // type. However, that requires substantially more matcher support than the
1900c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // following hack.
1901c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
1902c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // Change the operand to point to a temporary token.
1903c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  StringRef Base = Op->getToken();
1904f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar  SmallString<16> Tmp;
1905f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar  Tmp += Base;
1906f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar  Tmp += ' ';
1907f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar  Op->setTokenValue(Tmp.str());
1908c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
1909fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  // If this instruction starts with an 'f', then it is a floating point stack
1910fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  // instruction.  These come in up to three forms for 32-bit, 64-bit, and
1911fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  // 80-bit floating point, which use the suffixes s,l,t respectively.
1912fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  //
1913fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  // Otherwise, we assume that this may be an integer instruction, which comes
1914fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  // in 8/16/32/64-bit forms using the b,w,l,q suffixes respectively.
1915fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0";
191636b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier
1917c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // Check for the various suffix matches.
1918fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  Tmp[Base.size()] = Suffixes[0];
1919fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  unsigned ErrorInfoIgnore;
19204d9b7c234fd2510c27e6d74a3f0653efc0141580Duncan Sands  unsigned ErrorInfoMissingFeature = 0; // Init suppresses compiler warnings.
192119cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  unsigned Match1, Match2, Match3, Match4;
192236b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier
19236e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier  Match1 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
19246e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier                                isParsingIntelSyntax());
19253ca6382120c16e30151e19175d40480ee72de641Jim Grosbach  // If this returned as a missing feature failure, remember that.
19263ca6382120c16e30151e19175d40480ee72de641Jim Grosbach  if (Match1 == Match_MissingFeature)
19273ca6382120c16e30151e19175d40480ee72de641Jim Grosbach    ErrorInfoMissingFeature = ErrorInfoIgnore;
1928fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  Tmp[Base.size()] = Suffixes[1];
19296e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier  Match2 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
19306e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier                                isParsingIntelSyntax());
19313ca6382120c16e30151e19175d40480ee72de641Jim Grosbach  // If this returned as a missing feature failure, remember that.
19323ca6382120c16e30151e19175d40480ee72de641Jim Grosbach  if (Match2 == Match_MissingFeature)
19333ca6382120c16e30151e19175d40480ee72de641Jim Grosbach    ErrorInfoMissingFeature = ErrorInfoIgnore;
1934fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  Tmp[Base.size()] = Suffixes[2];
19356e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier  Match3 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
19366e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier                                isParsingIntelSyntax());
19373ca6382120c16e30151e19175d40480ee72de641Jim Grosbach  // If this returned as a missing feature failure, remember that.
19383ca6382120c16e30151e19175d40480ee72de641Jim Grosbach  if (Match3 == Match_MissingFeature)
19393ca6382120c16e30151e19175d40480ee72de641Jim Grosbach    ErrorInfoMissingFeature = ErrorInfoIgnore;
1940fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  Tmp[Base.size()] = Suffixes[3];
19416e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier  Match4 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
19426e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier                                isParsingIntelSyntax());
19433ca6382120c16e30151e19175d40480ee72de641Jim Grosbach  // If this returned as a missing feature failure, remember that.
19443ca6382120c16e30151e19175d40480ee72de641Jim Grosbach  if (Match4 == Match_MissingFeature)
19453ca6382120c16e30151e19175d40480ee72de641Jim Grosbach    ErrorInfoMissingFeature = ErrorInfoIgnore;
1946c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
1947c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // Restore the old token.
1948c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  Op->setTokenValue(Base);
1949c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
1950c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // If exactly one matched, then we treat that as a successful match (and the
1951c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // instruction will already have been filled in correctly, since the failing
1952c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // matches won't have modified it).
1953ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  unsigned NumSuccessfulMatches =
1954fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner    (Match1 == Match_Success) + (Match2 == Match_Success) +
1955fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner    (Match3 == Match_Success) + (Match4 == Match_Success);
19567036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner  if (NumSuccessfulMatches == 1) {
1957cb5dca38157a48c734660746e7f7340d5db7c2dbJim Grosbach    Inst.setLoc(IDLoc);
19587a2b624bb34374fe233f71cc5220d5ae0a0971cfChad Rosier    if (!MatchingInlineAsm)
195922685876ed7231f32f7d1698c00acab22825b74cChad Rosier      Out.EmitInstruction(Inst);
196022685876ed7231f32f7d1698c00acab22825b74cChad Rosier    Opcode = Inst.getOpcode();
1961c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar    return false;
19627036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner  }
1963c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
1964ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  // Otherwise, the match failed, try to produce a decent error message.
1965f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar
196609062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar  // If we had multiple suffix matches, then identify this as an ambiguous
196709062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar  // match.
1968ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  if (NumSuccessfulMatches > 1) {
196909062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    char MatchChars[4];
197009062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    unsigned NumMatches = 0;
1971fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner    if (Match1 == Match_Success) MatchChars[NumMatches++] = Suffixes[0];
1972fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner    if (Match2 == Match_Success) MatchChars[NumMatches++] = Suffixes[1];
1973fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner    if (Match3 == Match_Success) MatchChars[NumMatches++] = Suffixes[2];
1974fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner    if (Match4 == Match_Success) MatchChars[NumMatches++] = Suffixes[3];
197509062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar
197609062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    SmallString<126> Msg;
197709062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    raw_svector_ostream OS(Msg);
197809062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    OS << "ambiguous instructions require an explicit suffix (could be ";
197909062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    for (unsigned i = 0; i != NumMatches; ++i) {
198009062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar      if (i != 0)
198109062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar        OS << ", ";
198209062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar      if (i + 1 == NumMatches)
198309062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar        OS << "or ";
198409062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar      OS << "'" << Base << MatchChars[i] << "'";
198509062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    }
198609062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    OS << ")";
19877a2b624bb34374fe233f71cc5220d5ae0a0971cfChad Rosier    Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
1988ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    return true;
198909062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar  }
1990c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
1991a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  // Okay, we know that none of the variants matched successfully.
1992c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
1993a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  // If all of the instructions reported an invalid mnemonic, then the original
1994a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  // mnemonic was invalid.
1995fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  if ((Match1 == Match_MnemonicFail) && (Match2 == Match_MnemonicFail) &&
1996fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner      (Match3 == Match_MnemonicFail) && (Match4 == Match_MnemonicFail)) {
1997ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner    if (!WasOriginallyInvalidOperand) {
19987a2b624bb34374fe233f71cc5220d5ae0a0971cfChad Rosier      ArrayRef<SMRange> Ranges = MatchingInlineAsm ? EmptyRanges :
1999674101e6bb3742ae743e21e9b9ebec5946b1d273Chad Rosier        Op->getLocRange();
2000f82edaffb1a6d41bc89d86c69f53962e63621aadBenjamin Kramer      return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'",
20017a2b624bb34374fe233f71cc5220d5ae0a0971cfChad Rosier                   Ranges, MatchingInlineAsm);
2002ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner    }
2003ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner
2004ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner    // Recover location info for the operand if we know which was the problem.
200584125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier    if (ErrorInfo != ~0U) {
200684125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier      if (ErrorInfo >= Operands.size())
2007b4fdadef51ed254d9282356463c6b11ff8a102dfChad Rosier        return Error(IDLoc, "too few operands for instruction",
20087a2b624bb34374fe233f71cc5220d5ae0a0971cfChad Rosier                     EmptyRanges, MatchingInlineAsm);
2009c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
201084125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier      X86Operand *Operand = (X86Operand*)Operands[ErrorInfo];
2011d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner      if (Operand->getStartLoc().isValid()) {
2012d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner        SMRange OperandRange = Operand->getLocRange();
2013d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner        return Error(Operand->getStartLoc(), "invalid operand for instruction",
20147a2b624bb34374fe233f71cc5220d5ae0a0971cfChad Rosier                     OperandRange, MatchingInlineAsm);
2015d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner      }
2016ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner    }
2017ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner
2018b4fdadef51ed254d9282356463c6b11ff8a102dfChad Rosier    return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
20197a2b624bb34374fe233f71cc5220d5ae0a0971cfChad Rosier                 MatchingInlineAsm);
2020a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  }
2021c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
2022ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  // If one instruction matched with a missing feature, report this as a
2023ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  // missing feature.
2024fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  if ((Match1 == Match_MissingFeature) + (Match2 == Match_MissingFeature) +
2025fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner      (Match3 == Match_MissingFeature) + (Match4 == Match_MissingFeature) == 1){
20263ca6382120c16e30151e19175d40480ee72de641Jim Grosbach    std::string Msg = "instruction requires:";
20273ca6382120c16e30151e19175d40480ee72de641Jim Grosbach    unsigned Mask = 1;
20283ca6382120c16e30151e19175d40480ee72de641Jim Grosbach    for (unsigned i = 0; i < (sizeof(ErrorInfoMissingFeature)*8-1); ++i) {
20293ca6382120c16e30151e19175d40480ee72de641Jim Grosbach      if (ErrorInfoMissingFeature & Mask) {
20303ca6382120c16e30151e19175d40480ee72de641Jim Grosbach        Msg += " ";
20313ca6382120c16e30151e19175d40480ee72de641Jim Grosbach        Msg += getSubtargetFeatureName(ErrorInfoMissingFeature & Mask);
20323ca6382120c16e30151e19175d40480ee72de641Jim Grosbach      }
20333ca6382120c16e30151e19175d40480ee72de641Jim Grosbach      Mask <<= 1;
20343ca6382120c16e30151e19175d40480ee72de641Jim Grosbach    }
20353ca6382120c16e30151e19175d40480ee72de641Jim Grosbach    return Error(IDLoc, Msg, EmptyRanges, MatchingInlineAsm);
2036ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  }
2037c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
2038a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  // If one instruction matched with an invalid operand, report this as an
2039a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  // operand failure.
2040fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  if ((Match1 == Match_InvalidOperand) + (Match2 == Match_InvalidOperand) +
2041fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner      (Match3 == Match_InvalidOperand) + (Match4 == Match_InvalidOperand) == 1){
2042b4fdadef51ed254d9282356463c6b11ff8a102dfChad Rosier    Error(IDLoc, "invalid operand for instruction", EmptyRanges,
20437a2b624bb34374fe233f71cc5220d5ae0a0971cfChad Rosier          MatchingInlineAsm);
2044a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner    return true;
2045a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  }
2046c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
2047ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  // If all of these were an outright failure, report it in a useless way.
2048b4fdadef51ed254d9282356463c6b11ff8a102dfChad Rosier  Error(IDLoc, "unknown use of instruction mnemonic without a size suffix",
20497a2b624bb34374fe233f71cc5220d5ae0a0971cfChad Rosier        EmptyRanges, MatchingInlineAsm);
2050c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  return true;
2051c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar}
2052c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
2053c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
2054dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patelbool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
2055537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner  StringRef IDVal = DirectiveID.getIdentifier();
2056537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner  if (IDVal == ".word")
2057537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner    return ParseDirectiveWord(2, DirectiveID.getLoc());
2058bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng  else if (IDVal.startswith(".code"))
2059bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    return ParseDirectiveCode(IDVal, DirectiveID.getLoc());
20603c4ecd7dab5567017ad573769b0af484479bac6fChad Rosier  else if (IDVal.startswith(".att_syntax")) {
20613c4ecd7dab5567017ad573769b0af484479bac6fChad Rosier    getParser().setAssemblerDialect(0);
20623c4ecd7dab5567017ad573769b0af484479bac6fChad Rosier    return false;
20633c4ecd7dab5567017ad573769b0af484479bac6fChad Rosier  } else if (IDVal.startswith(".intel_syntax")) {
20640db58bfecea020ffcdfa1fc6458995371e1c3c50Devang Patel    getParser().setAssemblerDialect(1);
2065be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel    if (getLexer().isNot(AsmToken::EndOfStatement)) {
2066be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel      if(Parser.getTok().getString() == "noprefix") {
206776bd9386f1e1487a49c7c34ff95078dea20e3154Craig Topper        // FIXME : Handle noprefix
206876bd9386f1e1487a49c7c34ff95078dea20e3154Craig Topper        Parser.Lex();
2069be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel      } else
207076bd9386f1e1487a49c7c34ff95078dea20e3154Craig Topper        return true;
2071be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel    }
2072be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel    return false;
2073be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel  }
2074537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner  return true;
2075537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner}
2076537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner
2077537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner/// ParseDirectiveWord
2078537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner///  ::= .word [ expression (, expression)* ]
2079dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patelbool X86AsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
2080537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2081537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner    for (;;) {
2082537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner      const MCExpr *Value;
2083cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach      if (getParser().parseExpression(Value))
2084537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner        return true;
208536b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier
20861ced208be9cab0f994c5df9000da36bc313b2507Eric Christopher      getParser().getStreamer().EmitValue(Value, Size);
208736b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier
2088537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner      if (getLexer().is(AsmToken::EndOfStatement))
2089537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner        break;
209036b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier
2091537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner      // FIXME: Improve diagnostic.
2092537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner      if (getLexer().isNot(AsmToken::Comma))
2093537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner        return Error(L, "unexpected token in directive");
2094537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner      Parser.Lex();
2095537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner    }
2096537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner  }
209736b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier
2098537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner  Parser.Lex();
2099537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner  return false;
2100537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner}
2101537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner
2102bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng/// ParseDirectiveCode
2103bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng///  ::= .code32 | .code64
2104dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patelbool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
2105bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng  if (IDVal == ".code32") {
2106bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    Parser.Lex();
2107bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    if (is64BitMode()) {
2108bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng      SwitchMode();
2109bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng      getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
2110bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    }
2111bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng  } else if (IDVal == ".code64") {
2112bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    Parser.Lex();
2113bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    if (!is64BitMode()) {
2114bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng      SwitchMode();
2115bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng      getParser().getStreamer().EmitAssemblerFlag(MCAF_Code64);
2116bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    }
2117bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng  } else {
2118bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    return Error(L, "unexpected directive " + IDVal);
2119bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng  }
2120537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner
2121bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng  return false;
2122bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng}
2123537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner
2124092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar// Force static initialization.
2125092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbarextern "C" void LLVMInitializeX86AsmParser() {
2126dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patel  RegisterMCAsmParser<X86AsmParser> X(TheX86_32Target);
2127dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patel  RegisterMCAsmParser<X86AsmParser> Y(TheX86_64Target);
2128092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar}
21290e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar
21300692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER
21310692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION
21323ca6382120c16e30151e19175d40480ee72de641Jim Grosbach#define GET_SUBTARGET_FEATURE_NAME
21330e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar#include "X86GenAsmMatcher.inc"
2134