X86AsmParser.cpp revision 4fb25b7d799ea27a2c98a4d9bcf7469cc685db47
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
17316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  union {
17416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    struct {
17520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar      const char *Data;
17620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar      unsigned Length;
17720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    } Tok;
17820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
17920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    struct {
18016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      unsigned RegNo;
18116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    } Reg;
18216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
18316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    struct {
1848c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar      const MCExpr *Val;
185efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier      bool NeedAsmRewrite;
18616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    } Imm;
18716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
18816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    struct {
18916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      unsigned SegReg;
1908c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar      const MCExpr *Disp;
19116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      unsigned BaseReg;
19216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      unsigned IndexReg;
19316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      unsigned Scale;
194c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel      unsigned Size;
19596d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier      bool NeedSizeDir;
19616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    } Mem;
197dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar  };
19816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
1990a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner  X86Operand(KindTy K, SMLoc Start, SMLoc End)
2001f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner    : Kind(K), StartLoc(Start), EndLoc(End) {}
201c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
2021f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner  /// getStartLoc - Get the location of the first token of this operand.
2031f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner  SMLoc getStartLoc() const { return StartLoc; }
2041f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner  /// getEndLoc - Get the location of the last token of this operand.
2051f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner  SMLoc getEndLoc() const { return EndLoc; }
2067d4e989da972c2e9c89dad2d4e8f6ff9e1c73394Chad Rosier  /// getLocRange - Get the range between the first and last token of this
2077d4e989da972c2e9c89dad2d4e8f6ff9e1c73394Chad Rosier  /// operand.
208d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner  SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
2095a719fcb5ea91ec4e7af6fc2e48ec31774a859ddChad Rosier  /// getOffsetOfLoc - Get the location of the offset operator.
2105a719fcb5ea91ec4e7af6fc2e48ec31774a859ddChad Rosier  SMLoc getOffsetOfLoc() const { return OffsetOfLoc; }
2111f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner
212b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbach  virtual void print(raw_ostream &OS) const {}
213b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar
21420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  StringRef getToken() const {
21520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    assert(Kind == Token && "Invalid access!");
21620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    return StringRef(Tok.Data, Tok.Length);
21720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  }
218c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  void setTokenValue(StringRef Value) {
219c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar    assert(Kind == Token && "Invalid access!");
220c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar    Tok.Data = Value.data();
221c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar    Tok.Length = Value.size();
222c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  }
22320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
22416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  unsigned getReg() const {
22516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    assert(Kind == Register && "Invalid access!");
22616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    return Reg.RegNo;
22716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
22816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
2298c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar  const MCExpr *getImm() const {
230022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Immediate && "Invalid access!");
231022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Imm.Val;
232022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
233022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar
234efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier  bool needAsmRewrite() const {
235efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier    assert(Kind == Immediate && "Invalid access!");
236efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier    return Imm.NeedAsmRewrite;
237efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier  }
238efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier
2398c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar  const MCExpr *getMemDisp() const {
240022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Memory && "Invalid access!");
241022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Mem.Disp;
242022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
243022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  unsigned getMemSegReg() const {
244022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Memory && "Invalid access!");
245022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Mem.SegReg;
246022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
247022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  unsigned getMemBaseReg() const {
248022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Memory && "Invalid access!");
249022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Mem.BaseReg;
250022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
251022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  unsigned getMemIndexReg() const {
252022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Memory && "Invalid access!");
253022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Mem.IndexReg;
254022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
255022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  unsigned getMemScale() const {
256022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(Kind == Memory && "Invalid access!");
257022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    return Mem.Scale;
258022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  }
259022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar
260a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar  bool isToken() const {return Kind == Token; }
26120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
26220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  bool isImm() const { return Kind == Immediate; }
263f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
26462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar  bool isImmSExti16i8() const {
2655fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar    if (!isImm())
2665fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar      return false;
2675fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar
26862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // If this isn't a constant expr, just assume it fits and let relaxation
26962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // handle it.
27062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
27162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    if (!CE)
27262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar      return true;
27362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar
27462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // Otherwise, check the value is in a range that makes sense for this
27562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // extension.
276b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    return isImmSExti16i8Value(CE->getValue());
27762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar  }
27862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar  bool isImmSExti32i8() const {
27962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    if (!isImm())
28062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar      return false;
2815fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar
28262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // If this isn't a constant expr, just assume it fits and let relaxation
28362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // handle it.
28462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
28562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    if (!CE)
28662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar      return true;
28762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar
28862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // Otherwise, check the value is in a range that makes sense for this
28962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // extension.
290b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    return isImmSExti32i8Value(CE->getValue());
2915fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar  }
292c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby  bool isImmZExtu32u8() const {
293c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby    if (!isImm())
294c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby      return false;
295c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby
296c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby    // If this isn't a constant expr, just assume it fits and let relaxation
297c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby    // handle it.
298c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
299c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby    if (!CE)
300c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby      return true;
301c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby
302c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby    // Otherwise, check the value is in a range that makes sense for this
303c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby    // extension.
304b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    return isImmZExtu32u8Value(CE->getValue());
305c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby  }
30662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar  bool isImmSExti64i8() const {
3071fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar    if (!isImm())
3081fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar      return false;
3091fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar
31062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // If this isn't a constant expr, just assume it fits and let relaxation
31162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // handle it.
31262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
31362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    if (!CE)
31462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar      return true;
31562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar
31662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // Otherwise, check the value is in a range that makes sense for this
31762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // extension.
318b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    return isImmSExti64i8Value(CE->getValue());
31962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar  }
32062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar  bool isImmSExti64i32() const {
32162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    if (!isImm())
32262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar      return false;
3231fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar
32462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // If this isn't a constant expr, just assume it fits and let relaxation
32562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // handle it.
32662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
32762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    if (!CE)
32862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar      return true;
32962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar
33062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // Otherwise, check the value is in a range that makes sense for this
33162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar    // extension.
332b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    return isImmSExti64i32Value(CE->getValue());
3331fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar  }
3341fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar
33596d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier  unsigned getMemSize() const {
33696d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier    assert(Kind == Memory && "Invalid access!");
33796d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier    return Mem.Size;
33896d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier  }
33996d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier
340a703fb9e5e86ed29f7334736f7c085ec81a2006fChad Rosier  bool isOffsetOf() const {
341c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier    return OffsetOfLoc.getPointer();
342a703fb9e5e86ed29f7334736f7c085ec81a2006fChad Rosier  }
343a703fb9e5e86ed29f7334736f7c085ec81a2006fChad Rosier
344c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier  bool needAddressOf() const {
345c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier    return AddressOf;
346c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier  }
347c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier
34896d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier  bool needSizeDirective() const {
34996d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier    assert(Kind == Memory && "Invalid access!");
35096d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier    return Mem.NeedSizeDir;
35196d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier  }
35296d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier
35320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  bool isMem() const { return Kind == Memory; }
35436b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier  bool isMem8() const {
355f9e008bf673a8eeb04766bfc99f51068608809d2Chad Rosier    return Kind == Memory && (!Mem.Size || Mem.Size == 8);
356c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
35736b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier  bool isMem16() const {
358f9e008bf673a8eeb04766bfc99f51068608809d2Chad Rosier    return Kind == Memory && (!Mem.Size || Mem.Size == 16);
359c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
36036b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier  bool isMem32() const {
361f9e008bf673a8eeb04766bfc99f51068608809d2Chad Rosier    return Kind == Memory && (!Mem.Size || Mem.Size == 32);
362c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
36336b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier  bool isMem64() const {
364f9e008bf673a8eeb04766bfc99f51068608809d2Chad Rosier    return Kind == Memory && (!Mem.Size || Mem.Size == 64);
365c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
36636b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier  bool isMem80() const {
367f9e008bf673a8eeb04766bfc99f51068608809d2Chad Rosier    return Kind == Memory && (!Mem.Size || Mem.Size == 80);
368c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
36936b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier  bool isMem128() const {
370f9e008bf673a8eeb04766bfc99f51068608809d2Chad Rosier    return Kind == Memory && (!Mem.Size || Mem.Size == 128);
371c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
37236b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier  bool isMem256() const {
373f9e008bf673a8eeb04766bfc99f51068608809d2Chad Rosier    return Kind == Memory && (!Mem.Size || Mem.Size == 256);
374c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
37520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
37675dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper  bool isMemVX32() const {
37775dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper    return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
37875dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper      getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM15;
37975dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper  }
38075dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper  bool isMemVY32() const {
38175dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper    return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
38275dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper      getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM15;
38375dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper  }
38475dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper  bool isMemVX64() const {
38575dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper    return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
38675dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper      getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM15;
38775dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper  }
38875dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper  bool isMemVY64() const {
38975dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper    return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
39075dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper      getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM15;
39175dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper  }
39275dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper
393b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  bool isAbsMem() const {
394b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
3957b9147afa7d1875353e1c1347b6b6cf71f548229Daniel Dunbar      !getMemIndexReg() && getMemScale() == 1;
396b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  }
397b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar
39820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  bool isReg() const { return Kind == Register; }
39920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
4009c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
4019c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar    // Add as immediates when possible.
4029c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
4039c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
4049c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar    else
4059c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar      Inst.addOperand(MCOperand::CreateExpr(Expr));
4069c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar  }
4079c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar
4085c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar  void addRegOperands(MCInst &Inst, unsigned N) const {
40920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    assert(N == 1 && "Invalid number of operands!");
41020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getReg()));
41120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  }
41220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
4135c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar  void addImmOperands(MCInst &Inst, unsigned N) const {
41420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    assert(N == 1 && "Invalid number of operands!");
4159c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar    addExpr(Inst, getImm());
41620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  }
41720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
41836b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier  void addMem8Operands(MCInst &Inst, unsigned N) const {
41936b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier    addMemOperands(Inst, N);
420c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
42136b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier  void addMem16Operands(MCInst &Inst, unsigned N) const {
42236b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier    addMemOperands(Inst, N);
423c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
42436b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier  void addMem32Operands(MCInst &Inst, unsigned N) const {
42536b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier    addMemOperands(Inst, N);
426c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
42736b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier  void addMem64Operands(MCInst &Inst, unsigned N) const {
42836b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier    addMemOperands(Inst, N);
429c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
43036b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier  void addMem80Operands(MCInst &Inst, unsigned N) const {
43136b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier    addMemOperands(Inst, N);
432c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
43336b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier  void addMem128Operands(MCInst &Inst, unsigned N) const {
43436b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier    addMemOperands(Inst, N);
435c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
43636b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier  void addMem256Operands(MCInst &Inst, unsigned N) const {
43775dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper    addMemOperands(Inst, N);
43875dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper  }
43975dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper  void addMemVX32Operands(MCInst &Inst, unsigned N) const {
44075dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper    addMemOperands(Inst, N);
44175dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper  }
44275dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper  void addMemVY32Operands(MCInst &Inst, unsigned N) const {
44375dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper    addMemOperands(Inst, N);
44475dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper  }
44575dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper  void addMemVX64Operands(MCInst &Inst, unsigned N) const {
44675dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper    addMemOperands(Inst, N);
44775dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper  }
44875dc33a60b65bbbf2253b0b916df1d36a4da4237Craig Topper  void addMemVY64Operands(MCInst &Inst, unsigned N) const {
44936b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier    addMemOperands(Inst, N);
450c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel  }
451c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel
4525c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar  void addMemOperands(MCInst &Inst, unsigned N) const {
453ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar    assert((N == 5) && "Invalid number of operands!");
45420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
45520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    Inst.addOperand(MCOperand::CreateImm(getMemScale()));
45620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemIndexReg()));
4579c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar    addExpr(Inst, getMemDisp());
458ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
459ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar  }
460ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar
461b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  void addAbsMemOperands(MCInst &Inst, unsigned N) const {
462b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    assert((N == 1) && "Invalid number of operands!");
463b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby    // Add as immediates when possible.
464b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
465b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
466b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby    else
467b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby      Inst.addOperand(MCOperand::CreateExpr(getMemDisp()));
468b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  }
469b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar
470b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner  static X86Operand *CreateToken(StringRef Str, SMLoc Loc) {
4713ebe59c892051375623fea55e977ff559fdb3323Jordan Rose    SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size());
472f82edaffb1a6d41bc89d86c69f53962e63621aadBenjamin Kramer    X86Operand *Res = new X86Operand(Token, Loc, EndLoc);
47329ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Tok.Data = Str.data();
47429ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Tok.Length = Str.size();
47520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar    return Res;
47620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar  }
47720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
478c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier  static X86Operand *CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc,
479c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier                               bool AddressOf = false,
480c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier                               SMLoc OffsetOfLoc = SMLoc()) {
4811f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner    X86Operand *Res = new X86Operand(Register, StartLoc, EndLoc);
48229ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Reg.RegNo = RegNo;
483c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier    Res->AddressOf = AddressOf;
484c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier    Res->OffsetOfLoc = OffsetOfLoc;
48529ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    return Res;
48616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
48720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
488efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier  static X86Operand *CreateImm(const MCExpr *Val, SMLoc StartLoc, SMLoc EndLoc,
489efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier                               bool NeedRewrite = true){
490b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner    X86Operand *Res = new X86Operand(Immediate, StartLoc, EndLoc);
49129ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Imm.Val = Val;
492efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier    Res->Imm.NeedAsmRewrite = NeedRewrite;
49329ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    return Res;
49416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
49520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar
496b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  /// Create an absolute memory operand.
4974284e1795dd47d9638bb4fbd455ddb7e2e710e80Chad Rosier  static X86Operand *CreateMem(const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc,
4987109fbe98260d7a574762f5b9920d3d8e99052e3Chad Rosier                               unsigned Size = 0, bool NeedSizeDir = false) {
499b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc);
500b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    Res->Mem.SegReg   = 0;
501b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    Res->Mem.Disp     = Disp;
502b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    Res->Mem.BaseReg  = 0;
503b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    Res->Mem.IndexReg = 0;
5047b9147afa7d1875353e1c1347b6b6cf71f548229Daniel Dunbar    Res->Mem.Scale    = 1;
505c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel    Res->Mem.Size     = Size;
50696d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier    Res->Mem.NeedSizeDir = NeedSizeDir;
5077109fbe98260d7a574762f5b9920d3d8e99052e3Chad Rosier    Res->AddressOf = false;
508b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    return Res;
509b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  }
510b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar
511b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar  /// Create a generalized memory operand.
512309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner  static X86Operand *CreateMem(unsigned SegReg, const MCExpr *Disp,
513309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner                               unsigned BaseReg, unsigned IndexReg,
514c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel                               unsigned Scale, SMLoc StartLoc, SMLoc EndLoc,
515c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier                               unsigned Size = 0, bool NeedSizeDir = false) {
516b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    // We should never just have a displacement, that should be parsed as an
517b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar    // absolute memory operand.
518c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar    assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
519c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar
520022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    // The scale should always be one of {1,2,4,8}.
521022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar    assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
52216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar           "Invalid scale!");
5230a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner    X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc);
52429ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Mem.SegReg   = SegReg;
52529ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Mem.Disp     = Disp;
52629ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Mem.BaseReg  = BaseReg;
52729ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Mem.IndexReg = IndexReg;
52829ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    Res->Mem.Scale    = Scale;
529c59d9df2487accc82c2d128bba2aaf029c4a077dDevang Patel    Res->Mem.Size     = Size;
53096d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier    Res->Mem.NeedSizeDir = NeedSizeDir;
531b789b949b60c9a28686e638f75b2640d16d7144eNAKAMURA Takumi    Res->AddressOf = false;
53229ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    return Res;
53316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
53416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar};
53516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
53637dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner} // end anonymous namespace.
53716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
538dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patelbool X86AsmParser::isSrcOp(X86Operand &Op) {
53959ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  unsigned basereg = is64BitMode() ? X86::RSI : X86::ESI;
54096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger
54196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  return (Op.isMem() &&
54296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    (Op.Mem.SegReg == 0 || Op.Mem.SegReg == X86::DS) &&
54396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    isa<MCConstantExpr>(Op.Mem.Disp) &&
54496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
54596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    Op.Mem.BaseReg == basereg && Op.Mem.IndexReg == 0);
54696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger}
54796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger
548dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patelbool X86AsmParser::isDstOp(X86Operand &Op) {
54959ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  unsigned basereg = is64BitMode() ? X86::RDI : X86::EDI;
55096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger
55136b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier  return Op.isMem() &&
5520f5ab7c5f392d8207a4b0c5bf1f8b274a9f410dfKevin Enderby    (Op.Mem.SegReg == 0 || Op.Mem.SegReg == X86::ES) &&
55396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    isa<MCConstantExpr>(Op.Mem.Disp) &&
55496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
55596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    Op.Mem.BaseReg == basereg && Op.Mem.IndexReg == 0;
55696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger}
55716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
558dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patelbool X86AsmParser::ParseRegister(unsigned &RegNo,
559dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patel                                 SMLoc &StartLoc, SMLoc &EndLoc) {
56023075746a1418f281bc2a088ea85560bfd833599Chris Lattner  RegNo = 0;
5618e70b5506ec0d7a6c2740bc89cd1b8f12a78b24fBenjamin Kramer  const AsmToken &PercentTok = Parser.getTok();
5628e70b5506ec0d7a6c2740bc89cd1b8f12a78b24fBenjamin Kramer  StartLoc = PercentTok.getLoc();
5638e70b5506ec0d7a6c2740bc89cd1b8f12a78b24fBenjamin Kramer
5648e70b5506ec0d7a6c2740bc89cd1b8f12a78b24fBenjamin Kramer  // If we encounter a %, ignore it. This code handles registers with and
5658e70b5506ec0d7a6c2740bc89cd1b8f12a78b24fBenjamin Kramer  // without the prefix, unprefixed registers can occur in cfi directives.
5668e70b5506ec0d7a6c2740bc89cd1b8f12a78b24fBenjamin Kramer  if (!isParsingIntelSyntax() && PercentTok.is(AsmToken::Percent))
567d37ad247cc04c2a436e537767ac1aec709901594Devang Patel    Parser.Lex(); // Eat percent token.
5687b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby
56918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
5703ebe59c892051375623fea55e977ff559fdb3323Jordan Rose  EndLoc = Tok.getEndLoc();
5713ebe59c892051375623fea55e977ff559fdb3323Jordan Rose
5721aea430b8834f7bed3a14eda5027eac2133d6496Devang Patel  if (Tok.isNot(AsmToken::Identifier)) {
573be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel    if (isParsingIntelSyntax()) return true;
5745efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer    return Error(StartLoc, "invalid register name",
5753ebe59c892051375623fea55e977ff559fdb3323Jordan Rose                 SMRange(StartLoc, EndLoc));
5761aea430b8834f7bed3a14eda5027eac2133d6496Devang Patel  }
57716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
5787b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby  RegNo = MatchRegisterName(Tok.getString());
579f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
58033d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner  // If the match failed, try the register name as lowercase.
58133d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner  if (RegNo == 0)
582590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer    RegNo = MatchRegisterName(Tok.getString().lower());
583c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
5845de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng  if (!is64BitMode()) {
5855de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng    // FIXME: This should be done using Requires<In32BitMode> and
5865de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng    // Requires<In64BitMode> so "eiz" usage in 64-bit instructions can be also
5875de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng    // checked.
5885de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng    // FIXME: Check AH, CH, DH, BH cannot be used in an instruction requiring a
5895de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng    // REX prefix.
5905de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng    if (RegNo == X86::RIZ ||
5915de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng        X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo) ||
5925de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng        X86II::isX86_64NonExtLowByteReg(RegNo) ||
5935de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng        X86II::isX86_64ExtendedReg(RegNo))
5945efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer      return Error(StartLoc, "register %"
5955efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer                   + Tok.getString() + " is only available in 64-bit mode",
5963ebe59c892051375623fea55e977ff559fdb3323Jordan Rose                   SMRange(StartLoc, EndLoc));
5975de728cfe1a922ac9b13546dca94526b2fa693b6Evan Cheng  }
5983c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes
59933d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner  // Parse "%st" as "%st(0)" and "%st(1)", which is multiple tokens.
60033d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner  if (RegNo == 0 && (Tok.getString() == "st" || Tok.getString() == "ST")) {
601e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    RegNo = X86::ST0;
602e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    Parser.Lex(); // Eat 'st'
603f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
604e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    // Check to see if we have '(4)' after %st.
605e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    if (getLexer().isNot(AsmToken::LParen))
606e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner      return false;
607e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    // Lex the paren.
608e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    getParser().Lex();
609e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner
610e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    const AsmToken &IntTok = Parser.getTok();
611e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    if (IntTok.isNot(AsmToken::Integer))
612e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner      return Error(IntTok.getLoc(), "expected stack index");
613e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    switch (IntTok.getIntVal()) {
614e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 0: RegNo = X86::ST0; break;
615e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 1: RegNo = X86::ST1; break;
616e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 2: RegNo = X86::ST2; break;
617e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 3: RegNo = X86::ST3; break;
618e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 4: RegNo = X86::ST4; break;
619e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 5: RegNo = X86::ST5; break;
620e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 6: RegNo = X86::ST6; break;
621e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    case 7: RegNo = X86::ST7; break;
622e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    default: return Error(IntTok.getLoc(), "invalid stack index");
623e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    }
624f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
625e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    if (getParser().Lex().isNot(AsmToken::RParen))
626e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner      return Error(Parser.getTok().getLoc(), "expected ')'");
627f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
6283ebe59c892051375623fea55e977ff559fdb3323Jordan Rose    EndLoc = Parser.getTok().getEndLoc();
629e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    Parser.Lex(); // Eat ')'
630e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner    return false;
631e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner  }
632f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
6333ebe59c892051375623fea55e977ff559fdb3323Jordan Rose  EndLoc = Parser.getTok().getEndLoc();
6343ebe59c892051375623fea55e977ff559fdb3323Jordan Rose
635645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner  // If this is "db[0-7]", match it as an alias
636645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner  // for dr[0-7].
637645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner  if (RegNo == 0 && Tok.getString().size() == 3 &&
638645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner      Tok.getString().startswith("db")) {
639645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    switch (Tok.getString()[2]) {
640645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '0': RegNo = X86::DR0; break;
641645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '1': RegNo = X86::DR1; break;
642645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '2': RegNo = X86::DR2; break;
643645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '3': RegNo = X86::DR3; break;
644645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '4': RegNo = X86::DR4; break;
645645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '5': RegNo = X86::DR5; break;
646645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '6': RegNo = X86::DR6; break;
647645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    case '7': RegNo = X86::DR7; break;
648645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    }
649f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
650645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    if (RegNo != 0) {
6513ebe59c892051375623fea55e977ff559fdb3323Jordan Rose      EndLoc = Parser.getTok().getEndLoc();
652645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner      Parser.Lex(); // Eat it.
653645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner      return false;
654645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner    }
655645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner  }
656f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
6571aea430b8834f7bed3a14eda5027eac2133d6496Devang Patel  if (RegNo == 0) {
658be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel    if (isParsingIntelSyntax()) return true;
6595efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer    return Error(StartLoc, "invalid register name",
6603ebe59c892051375623fea55e977ff559fdb3323Jordan Rose                 SMRange(StartLoc, EndLoc));
6611aea430b8834f7bed3a14eda5027eac2133d6496Devang Patel  }
6620e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar
663b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat identifier token.
66416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  return false;
665092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar}
666092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar
667dd929fc704054fa79cc1171354f95d91a5b62de2Devang PatelX86Operand *X86AsmParser::ParseOperand() {
668be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel  if (isParsingIntelSyntax())
6690a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel    return ParseIntelOperand();
6700a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  return ParseATTOperand();
6710a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel}
6720a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel
673d37ad247cc04c2a436e537767ac1aec709901594Devang Patel/// getIntelMemOperandSize - Return intel memory operand size.
674d37ad247cc04c2a436e537767ac1aec709901594Devang Patelstatic unsigned getIntelMemOperandSize(StringRef OpStr) {
67566b64bec6021e3f38af090429c7e41d1180df5a9Chad Rosier  unsigned Size = StringSwitch<unsigned>(OpStr)
676f58ae5dfc1c939e34e660a21b4ea7d192a37a322Chad Rosier    .Cases("BYTE", "byte", 8)
677f58ae5dfc1c939e34e660a21b4ea7d192a37a322Chad Rosier    .Cases("WORD", "word", 16)
678f58ae5dfc1c939e34e660a21b4ea7d192a37a322Chad Rosier    .Cases("DWORD", "dword", 32)
679f58ae5dfc1c939e34e660a21b4ea7d192a37a322Chad Rosier    .Cases("QWORD", "qword", 64)
680f58ae5dfc1c939e34e660a21b4ea7d192a37a322Chad Rosier    .Cases("XWORD", "xword", 80)
681f58ae5dfc1c939e34e660a21b4ea7d192a37a322Chad Rosier    .Cases("XMMWORD", "xmmword", 128)
682f58ae5dfc1c939e34e660a21b4ea7d192a37a322Chad Rosier    .Cases("YMMWORD", "ymmword", 256)
68366b64bec6021e3f38af090429c7e41d1180df5a9Chad Rosier    .Default(0);
68466b64bec6021e3f38af090429c7e41d1180df5a9Chad Rosier  return Size;
6850a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel}
6860a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel
687dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosierenum IntelBracExprState {
688dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  IBES_START,
689dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  IBES_LBRAC,
690dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  IBES_RBRAC,
691dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  IBES_REGISTER,
692dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  IBES_REGISTER_STAR,
693dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  IBES_REGISTER_STAR_INTEGER,
694dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  IBES_INTEGER,
695dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  IBES_INTEGER_STAR,
696dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  IBES_INDEX_REGISTER,
697dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  IBES_IDENTIFIER,
698dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  IBES_DISP_EXPR,
699dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  IBES_MINUS,
700dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  IBES_ERROR
701dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier};
702dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier
703dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosierclass IntelBracExprStateMachine {
704dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  IntelBracExprState State;
705dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  unsigned BaseReg, IndexReg, Scale;
706dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  int64_t Disp;
707dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier
708dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  unsigned TmpReg;
709dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  int64_t TmpInteger;
710dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier
711dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  bool isPlus;
712dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier
713dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosierpublic:
714dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  IntelBracExprStateMachine(MCAsmParser &parser) :
715dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    State(IBES_START), BaseReg(0), IndexReg(0), Scale(1), Disp(0),
716dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    TmpReg(0), TmpInteger(0), isPlus(true) {}
717dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier
718dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  unsigned getBaseReg() { return BaseReg; }
719dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  unsigned getIndexReg() { return IndexReg; }
720dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  unsigned getScale() { return Scale; }
721dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  int64_t getDisp() { return Disp; }
722dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  bool isValidEndState() { return State == IBES_RBRAC; }
723dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier
724dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  void onPlus() {
725dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    switch (State) {
726dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    default:
727dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_ERROR;
728dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
729dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case IBES_INTEGER:
730dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_START;
731dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      if (isPlus)
732dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        Disp += TmpInteger;
733dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      else
734dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        Disp -= TmpInteger;
735dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
736dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case IBES_REGISTER:
737dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_START;
738dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      // If we already have a BaseReg, then assume this is the IndexReg with a
739dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      // scale of 1.
740dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      if (!BaseReg) {
741dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        BaseReg = TmpReg;
742dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      } else {
743dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        assert (!IndexReg && "BaseReg/IndexReg already set!");
744dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        IndexReg = TmpReg;
745dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        Scale = 1;
746dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      }
747dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
748dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case IBES_INDEX_REGISTER:
749dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_START;
750dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
751dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    }
752dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    isPlus = true;
753dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  }
754dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  void onMinus() {
755dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    switch (State) {
756dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    default:
757dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_ERROR;
758dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
759dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case IBES_START:
760dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_MINUS;
761dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
762dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case IBES_INTEGER:
763dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_START;
764dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      if (isPlus)
765dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        Disp += TmpInteger;
766dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      else
767dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        Disp -= TmpInteger;
768dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
769dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case IBES_REGISTER:
770dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_START;
771dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      // If we already have a BaseReg, then assume this is the IndexReg with a
772dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      // scale of 1.
773dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      if (!BaseReg) {
774dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        BaseReg = TmpReg;
775dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      } else {
776dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        assert (!IndexReg && "BaseReg/IndexReg already set!");
777dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        IndexReg = TmpReg;
778dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        Scale = 1;
779dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      }
780dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
781dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case IBES_INDEX_REGISTER:
782dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_START;
783dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
784dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    }
785dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    isPlus = false;
786dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  }
787dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  void onRegister(unsigned Reg) {
788dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    switch (State) {
789dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    default:
790dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_ERROR;
791dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
792dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case IBES_START:
793dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_REGISTER;
794dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      TmpReg = Reg;
795dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
796dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case IBES_INTEGER_STAR:
797dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      assert (!IndexReg && "IndexReg already set!");
798dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_INDEX_REGISTER;
799dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      IndexReg = Reg;
800dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      Scale = TmpInteger;
801dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
802dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    }
803dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  }
804dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  void onDispExpr() {
805dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    switch (State) {
806dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    default:
807dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_ERROR;
808dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
809dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case IBES_START:
810dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_DISP_EXPR;
811dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
812dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    }
813dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  }
814dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  void onInteger(int64_t TmpInt) {
815dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    switch (State) {
816dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    default:
817dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_ERROR;
818dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
819dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case IBES_START:
820dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_INTEGER;
821dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      TmpInteger = TmpInt;
822dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
823dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case IBES_MINUS:
824dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_INTEGER;
825dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      TmpInteger = TmpInt;
826dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
827dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case IBES_REGISTER_STAR:
828dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      assert (!IndexReg && "IndexReg already set!");
829dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_INDEX_REGISTER;
830dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      IndexReg = TmpReg;
831dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      Scale = TmpInt;
832dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
833dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    }
834dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  }
835dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  void onStar() {
836dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    switch (State) {
837dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    default:
838dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_ERROR;
839dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
840dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case IBES_INTEGER:
841dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_INTEGER_STAR;
842dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
843dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case IBES_REGISTER:
844dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_REGISTER_STAR;
845dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
846dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    }
847dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  }
848dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  void onLBrac() {
849dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    switch (State) {
850dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    default:
851dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_ERROR;
852dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
853dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case IBES_RBRAC:
854dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_START;
855dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      isPlus = true;
856dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
857dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    }
858dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  }
859dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  void onRBrac() {
860dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    switch (State) {
861dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    default:
862dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_ERROR;
863dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
864dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case IBES_DISP_EXPR:
865dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_RBRAC;
866dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
867dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case IBES_INTEGER:
868dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_RBRAC;
869dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      if (isPlus)
870dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        Disp += TmpInteger;
871dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      else
872dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        Disp -= TmpInteger;
873dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
874dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case IBES_REGISTER:
875dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_RBRAC;
876dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      // If we already have a BaseReg, then assume this is the IndexReg with a
877dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      // scale of 1.
878dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      if (!BaseReg) {
879dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        BaseReg = TmpReg;
880dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      } else {
881dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        assert (!IndexReg && "BaseReg/IndexReg already set!");
882dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        IndexReg = TmpReg;
883dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        Scale = 1;
884dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      }
885dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
886dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case IBES_INDEX_REGISTER:
887dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      State = IBES_RBRAC;
888dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
889dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    }
890dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  }
891dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier};
892dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier
89365c88929e718f4fb0f57afb4c95b2e570759e99fChad RosierX86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg,
8947c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel                                                   unsigned Size) {
8954284e1795dd47d9638bb4fbd455ddb7e2e710e80Chad Rosier  const AsmToken &Tok = Parser.getTok();
8963ebe59c892051375623fea55e977ff559fdb3323Jordan Rose  SMLoc Start = Tok.getLoc(), End = Tok.getEndLoc();
897c798cc42831150f678b080c0994c1cc024bae653Devang Patel
898d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  // Eat '['
899d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  if (getLexer().isNot(AsmToken::LBrac))
900d37ad247cc04c2a436e537767ac1aec709901594Devang Patel    return ErrorOperand(Start, "Expected '[' token!");
901d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  Parser.Lex();
90236b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier
903dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  unsigned TmpReg = 0;
904dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier
905dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  // Try to handle '[' 'symbol' ']'
906d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  if (getLexer().is(AsmToken::Identifier)) {
907dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    if (ParseRegister(TmpReg, Start, End)) {
908dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      const MCExpr *Disp;
909dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      if (getParser().ParseExpression(Disp, End))
910dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        return 0;
911dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier
912d37ad247cc04c2a436e537767ac1aec709901594Devang Patel      if (getLexer().isNot(AsmToken::RBrac))
9133ebe59c892051375623fea55e977ff559fdb3323Jordan Rose        return ErrorOperand(Parser.getTok().getLoc(), "Expected ']' token!");
9144fb25b7d799ea27a2c98a4d9bcf7469cc685db47Chad Rosier      // Adjust the EndLoc due to the ']'.
9154fb25b7d799ea27a2c98a4d9bcf7469cc685db47Chad Rosier      End = SMLoc::getFromPointer(Parser.getTok().getEndLoc().getPointer()-1);
91685d5aaecd03ca4bc6e406ee88c72a4ba8878bb2bDevang Patel      Parser.Lex();
917c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier      return X86Operand::CreateMem(Disp, Start, End, Size);
91885d5aaecd03ca4bc6e406ee88c72a4ba8878bb2bDevang Patel    }
9192fbc239e4fbdd12c24fb2cf9e3e915861fc12030Chad Rosier  }
9202fbc239e4fbdd12c24fb2cf9e3e915861fc12030Chad Rosier
921dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  // Parse [ BaseReg + Scale*IndexReg + Disp ].
922dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  bool Done = false;
923dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  IntelBracExprStateMachine SM(Parser);
924dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier
925dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  // If we parsed a register, then the end loc has already been set and
926dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  // the identifier has already been lexed.  We also need to update the
927dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  // state.
928dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  if (TmpReg)
929dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    SM.onRegister(TmpReg);
930dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier
931dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  const MCExpr *Disp = 0;
932dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  while (!Done) {
933dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    bool UpdateLocLex = true;
934dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier
935dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    // The period in the dot operator (e.g., [ebx].foo.bar) is parsed as an
936dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    // identifier.  Don't try an parse it as a register.
937dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    if (Tok.getString().startswith("."))
938dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
939dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier
940dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    switch (getLexer().getKind()) {
941dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    default: {
942dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      if (SM.isValidEndState()) {
943dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        Done = true;
944dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        break;
945dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      }
946dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      return ErrorOperand(Tok.getLoc(), "Unexpected token!");
947dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    }
948dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case AsmToken::Identifier: {
949dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      // This could be a register or a displacement expression.
950dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      if(!ParseRegister(TmpReg, Start, End)) {
951dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        SM.onRegister(TmpReg);
952dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        UpdateLocLex = false;
953dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        break;
954dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      } else if (!getParser().ParseExpression(Disp, End)) {
955dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        SM.onDispExpr();
956dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        UpdateLocLex = false;
957dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier        break;
958dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      }
959dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      return ErrorOperand(Tok.getLoc(), "Unexpected identifier!");
960dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    }
961dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case AsmToken::Integer: {
9624284e1795dd47d9638bb4fbd455ddb7e2e710e80Chad Rosier      int64_t Val = Tok.getIntVal();
963dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      SM.onInteger(Val);
964dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      break;
965f2d213745e07e884c1616f2f3d0b78f9e918e5dbDevang Patel    }
966dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case AsmToken::Plus:    SM.onPlus(); break;
967dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case AsmToken::Minus:   SM.onMinus(); break;
968dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case AsmToken::Star:    SM.onStar(); break;
969dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case AsmToken::LBrac:   SM.onLBrac(); break;
970dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    case AsmToken::RBrac:   SM.onRBrac(); break;
971dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    }
972dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    if (!Done && UpdateLocLex) {
973dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      End = Tok.getLoc();
974dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      Parser.Lex(); // Consume the token.
9752fbc239e4fbdd12c24fb2cf9e3e915861fc12030Chad Rosier    }
9762fbc239e4fbdd12c24fb2cf9e3e915861fc12030Chad Rosier  }
977c798cc42831150f678b080c0994c1cc024bae653Devang Patel
978dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  if (!Disp)
979dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    Disp = MCConstantExpr::Create(SM.getDisp(), getContext());
980fdd3b30151bc391efce74f4592a9a3bb595565a2Devang Patel
981ddb53ef4a8aa526c293ff316c2134bf1629e6812Chad Rosier  // Parse the dot operator (e.g., [ebx].foo.bar).
9825e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier  if (Tok.getString().startswith(".")) {
9835e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier    SmallString<64> Err;
9845e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier    const MCExpr *NewDisp;
9855e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier    if (ParseIntelDotOperator(Disp, &NewDisp, Err))
9865e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier      return ErrorOperand(Tok.getLoc(), Err);
9875e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier
9883ebe59c892051375623fea55e977ff559fdb3323Jordan Rose    End = Parser.getTok().getEndLoc();
9895e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier    Parser.Lex();  // Eat the field.
9905e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier    Disp = NewDisp;
9915e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier  }
99222f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier
993dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  int BaseReg = SM.getBaseReg();
994dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  int IndexReg = SM.getIndexReg();
995dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier
996fdd3b30151bc391efce74f4592a9a3bb595565a2Devang Patel  // handle [-42]
997dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  if (!BaseReg && !IndexReg) {
998dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    if (!SegReg)
999dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      return X86Operand::CreateMem(Disp, Start, End);
1000dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier    else
1001dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier      return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, Start, End, Size);
1002dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  }
1003fdd3b30151bc391efce74f4592a9a3bb595565a2Devang Patel
1004dd2e8950222ab74157b1c083ffa77b0fbaf1d210Chad Rosier  int Scale = SM.getScale();
1005d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale,
1006c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier                               Start, End, Size);
1007d37ad247cc04c2a436e537767ac1aec709901594Devang Patel}
1008d37ad247cc04c2a436e537767ac1aec709901594Devang Patel
1009d37ad247cc04c2a436e537767ac1aec709901594Devang Patel/// ParseIntelMemOperand - Parse intel style memory operand.
10105b0f1b37639d57dec72972fe445880a8a99d8674Chad RosierX86Operand *X86AsmParser::ParseIntelMemOperand(unsigned SegReg, SMLoc Start) {
1011d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  const AsmToken &Tok = Parser.getTok();
1012c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier  SMLoc End;
1013d37ad247cc04c2a436e537767ac1aec709901594Devang Patel
1014d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  unsigned Size = getIntelMemOperandSize(Tok.getString());
1015d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  if (Size) {
1016d37ad247cc04c2a436e537767ac1aec709901594Devang Patel    Parser.Lex();
1017f58ae5dfc1c939e34e660a21b4ea7d192a37a322Chad Rosier    assert ((Tok.getString() == "PTR" || Tok.getString() == "ptr") &&
1018f58ae5dfc1c939e34e660a21b4ea7d192a37a322Chad Rosier            "Unexpected token!");
1019d37ad247cc04c2a436e537767ac1aec709901594Devang Patel    Parser.Lex();
1020d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  }
1021d37ad247cc04c2a436e537767ac1aec709901594Devang Patel
1022c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier  if (getLexer().is(AsmToken::LBrac))
10237c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel    return ParseIntelBracExpression(SegReg, Size);
10247c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel
10257c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel  if (!ParseRegister(SegReg, Start, End)) {
10267c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel    // Handel SegReg : [ ... ]
10277c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel    if (getLexer().isNot(AsmToken::Colon))
10287c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel      return ErrorOperand(Start, "Expected ':' token!");
10297c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel    Parser.Lex(); // Eat :
10307c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel    if (getLexer().isNot(AsmToken::LBrac))
10317c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel      return ErrorOperand(Start, "Expected '[' token!");
10327c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel    return ParseIntelBracExpression(SegReg, Size);
10337c64fe651ad4581ac66b6407116144442a8a7f03Devang Patel  }
1034d37ad247cc04c2a436e537767ac1aec709901594Devang Patel
1035d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext());
10363ebe59c892051375623fea55e977ff559fdb3323Jordan Rose  if (getParser().ParseExpression(Disp, End))
10373ebe59c892051375623fea55e977ff559fdb3323Jordan Rose    return 0;
103896d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier
103996d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier  bool NeedSizeDir = false;
1040c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier  bool IsVarDecl = false;
1041c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier  if (isParsingInlineAsm()) {
104296d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier    if (const MCSymbolRefExpr *SymRef = dyn_cast<MCSymbolRefExpr>(Disp)) {
104396d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier      const MCSymbol &Sym = SymRef->getSymbol();
104496d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier      // FIXME: The SemaLookup will fail if the name is anything other then an
104596d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier      // identifier.
104696d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier      // FIXME: Pass a valid SMLoc.
1047505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier      unsigned tLength, tSize, tType;
1048505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier      SemaCallback->LookupInlineAsmIdentifier(Sym.getName(), NULL, tLength,
1049505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier                                              tSize, tType, IsVarDecl);
1050c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier      if (!Size)
1051505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier        Size = tType * 8; // Size is in terms of bits in this context.
105296d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier      NeedSizeDir = Size > 0;
105396d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier    }
105496d58e64cfe88356f8be4ce622b829fbd9fb5908Chad Rosier  }
10552a784131fed4bc99c0ae96b5252a3fe0079a3079Chad Rosier  if (!isParsingInlineAsm())
1056c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier    return X86Operand::CreateMem(Disp, Start, End, Size);
1057c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier  else {
1058c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier    // If this is not a VarDecl then assume it is a FuncDecl or some other label
1059c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier    // reference.  We need an 'r' constraint here, so we need to create register
1060c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier    // operand to ensure proper matching.  Just pick a GPR based on the size of
1061c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier    // a pointer.
1062c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier    if (!IsVarDecl) {
1063c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier      unsigned RegNo = is64BitMode() ? X86::RBX : X86::EBX;
1064c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier      return X86Operand::CreateReg(RegNo, Start, End, /*AddressOf=*/true);
1065c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier    }
1066c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier
1067d4d96acb9117574510390af700ec0eca375f58f2Chad Rosier    // When parsing inline assembly we set the base register to a non-zero value
1068d4d96acb9117574510390af700ec0eca375f58f2Chad Rosier    // as we don't know the actual value at this time.  This is necessary to
1069d4d96acb9117574510390af700ec0eca375f58f2Chad Rosier    // get the matching correct in some cases.
10702a784131fed4bc99c0ae96b5252a3fe0079a3079Chad Rosier    return X86Operand::CreateMem(/*SegReg*/0, Disp, /*BaseReg*/1, /*IndexReg*/0,
1071c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier                                 /*Scale*/1, Start, End, Size, NeedSizeDir);
1072c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier  }
1073c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier}
1074c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier
107522f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier/// Parse the '.' operator.
10765e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosierbool X86AsmParser::ParseIntelDotOperator(const MCExpr *Disp,
10775e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier                                         const MCExpr **NewDisp,
10785e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier                                         SmallString<64> &Err) {
107922f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier  AsmToken Tok = *&Parser.getTok();
10805e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier  uint64_t OrigDispVal, DotDispVal;
10815e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier
10825e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier  // FIXME: Handle non-constant expressions.
10835e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier  if (const MCConstantExpr *OrigDisp = dyn_cast<MCConstantExpr>(Disp)) {
10845e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier    OrigDispVal = OrigDisp->getValue();
10855e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier  } else {
10865e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier    Err = "Non-constant offsets are not supported!";
10875e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier    return true;
10885e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier  }
108922f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier
109022f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier  // Drop the '.'.
109122f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier  StringRef DotDispStr = Tok.getString().drop_front(1);
109222f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier
109322f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier  // .Imm gets lexed as a real.
109422f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier  if (Tok.is(AsmToken::Real)) {
109522f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier    APInt DotDisp;
109622f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier    DotDispStr.getAsInteger(10, DotDisp);
10975e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier    DotDispVal = DotDisp.getZExtValue();
1098ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier  } else if (Tok.is(AsmToken::Identifier)) {
1099ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier    // We should only see an identifier when parsing the original inline asm.
1100ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier    // The front-end should rewrite this in terms of immediates.
1101ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier    assert (isParsingInlineAsm() && "Unexpected field name!");
1102ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier
1103ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier    unsigned DotDisp;
1104ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier    std::pair<StringRef, StringRef> BaseMember = DotDispStr.split('.');
1105ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier    if (SemaCallback->LookupInlineAsmField(BaseMember.first, BaseMember.second,
1106ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier                                           DotDisp)) {
1107ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier      Err = "Unable to lookup field reference!";
1108ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier      return true;
1109ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier    }
1110ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier    DotDispVal = DotDisp;
11115e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier  } else {
11125e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier    Err = "Unexpected token type!";
11135e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier    return true;
11145e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier  }
111522f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier
1116ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier  if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) {
1117ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier    SMLoc Loc = SMLoc::getFromPointer(DotDispStr.data());
1118ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier    unsigned Len = DotDispStr.size();
1119ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier    unsigned Val = OrigDispVal + DotDispVal;
1120ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier    InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_DotOperator, Loc, Len,
1121ec13022c392747ef166e6be738fc6f00bd7c52d3Chad Rosier                                                Val));
112222f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier  }
11235e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier
11245e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier  *NewDisp = MCConstantExpr::Create(OrigDispVal + DotDispVal, getContext());
11255e6b37fa3d5f555b0aba7b2594f28b359a22ea31Chad Rosier  return false;
112622f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier}
112722f441afbac90b2dc1e4315a7a6c50dd034af2dbChad Rosier
1128c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier/// Parse the 'offset' operator.  This operator is used to specify the
1129c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier/// location rather then the content of a variable.
1130c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad RosierX86Operand *X86AsmParser::ParseIntelOffsetOfOperator(SMLoc Start) {
1131c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier  SMLoc OffsetOfLoc = Start;
1132c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier  Parser.Lex(); // Eat offset.
1133c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier  Start = Parser.getTok().getLoc();
1134c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier  assert (Parser.getTok().is(AsmToken::Identifier) && "Expected an identifier");
1135c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier
11366e43157b5d39a713d4061f97629bf9107c6d25e0Chad Rosier  SMLoc End;
1137c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier  const MCExpr *Val;
1138c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier  if (getParser().ParseExpression(Val, End))
11397ab21c7a05509714358ac26530f5427de63113dfChad Rosier    return ErrorOperand(Start, "Unable to parse expression!");
1140c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier
11416e43157b5d39a713d4061f97629bf9107c6d25e0Chad Rosier  // Don't emit the offset operator.
11426e43157b5d39a713d4061f97629bf9107c6d25e0Chad Rosier  InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Skip, OffsetOfLoc, 7));
11436e43157b5d39a713d4061f97629bf9107c6d25e0Chad Rosier
1144c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier  // The offset operator will have an 'r' constraint, thus we need to create
1145c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier  // register operand to ensure proper matching.  Just pick a GPR based on
1146c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier  // the size of a pointer.
1147c0a14b86f7ad334c2a557c1ee4fff12e8d396fd0Chad Rosier  unsigned RegNo = is64BitMode() ? X86::RBX : X86::EBX;
1148c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier  return X86Operand::CreateReg(RegNo, Start, End, /*GetAddress=*/true,
1149c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier                               OffsetOfLoc);
1150d37ad247cc04c2a436e537767ac1aec709901594Devang Patel}
1151d37ad247cc04c2a436e537767ac1aec709901594Devang Patel
1152505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosierenum IntelOperatorKind {
1153505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier  IOK_LENGTH,
1154505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier  IOK_SIZE,
1155505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier  IOK_TYPE
1156505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier};
1157505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier
1158505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier/// Parse the 'LENGTH', 'TYPE' and 'SIZE' operators.  The LENGTH operator
1159505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier/// returns the number of elements in an array.  It returns the value 1 for
1160505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier/// non-array variables.  The SIZE operator returns the size of a C or C++
1161505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier/// variable.  A variable's size is the product of its LENGTH and TYPE.  The
1162505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier/// TYPE operator returns the size of a C or C++ type or variable. If the
1163505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier/// variable is an array, TYPE returns the size of a single element.
1164505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad RosierX86Operand *X86AsmParser::ParseIntelOperator(SMLoc Start, unsigned OpKind) {
1165efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier  SMLoc TypeLoc = Start;
1166efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier  Parser.Lex(); // Eat offset.
1167efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier  Start = Parser.getTok().getLoc();
1168efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier  assert (Parser.getTok().is(AsmToken::Identifier) && "Expected an identifier");
1169efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier
1170efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier  SMLoc End;
1171efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier  const MCExpr *Val;
1172efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier  if (getParser().ParseExpression(Val, End))
1173efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier    return 0;
1174efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier
1175505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier  unsigned Length = 0, Size = 0, Type = 0;
1176efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier  if (const MCSymbolRefExpr *SymRef = dyn_cast<MCSymbolRefExpr>(Val)) {
1177efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier    const MCSymbol &Sym = SymRef->getSymbol();
1178efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier    // FIXME: The SemaLookup will fail if the name is anything other then an
1179efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier    // identifier.
1180efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier    // FIXME: Pass a valid SMLoc.
1181c1ec207b615cb058d30dc642ee311ed06fe59cfeChad Rosier    bool IsVarDecl;
1182505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier    if (!SemaCallback->LookupInlineAsmIdentifier(Sym.getName(), NULL, Length,
1183505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier                                                 Size, Type, IsVarDecl))
11843da67ca97383f8d305cc732019a51157f9fce290Chad Rosier      return ErrorOperand(Start, "Unable to lookup expr!");
1185505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier  }
1186505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier  unsigned CVal;
1187505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier  switch(OpKind) {
1188505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier  default: llvm_unreachable("Unexpected operand kind!");
1189505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier  case IOK_LENGTH: CVal = Length; break;
1190505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier  case IOK_SIZE: CVal = Size; break;
1191505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier  case IOK_TYPE: CVal = Type; break;
1192efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier  }
1193efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier
1194efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier  // Rewrite the type operator and the C or C++ type or variable in terms of an
1195efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier  // immediate.  E.g. TYPE foo -> $$4
1196efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier  unsigned Len = End.getPointer() - TypeLoc.getPointer();
1197505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier  InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Imm, TypeLoc, Len, CVal));
1198efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier
1199505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier  const MCExpr *Imm = MCConstantExpr::Create(CVal, getContext());
1200efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier  return X86Operand::CreateImm(Imm, Start, End, /*NeedAsmRewrite*/false);
1201efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier}
1202efcb3d9c1cd9410949b4005fbe6f2817f8dfe395Chad Rosier
1203d37ad247cc04c2a436e537767ac1aec709901594Devang PatelX86Operand *X86AsmParser::ParseIntelOperand() {
1204d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  SMLoc Start = Parser.getTok().getLoc(), End;
12057ab21c7a05509714358ac26530f5427de63113dfChad Rosier  StringRef AsmTokStr = Parser.getTok().getString();
1206505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier
1207505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier  // Offset, length, type and size operators.
1208505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier  if (isParsingInlineAsm()) {
1209505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier    if (AsmTokStr == "offset" || AsmTokStr == "OFFSET")
1210505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier      return ParseIntelOffsetOfOperator(Start);
1211505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier    if (AsmTokStr == "length" || AsmTokStr == "LENGTH")
1212505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier      return ParseIntelOperator(Start, IOK_LENGTH);
1213505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier    if (AsmTokStr == "size" || AsmTokStr == "SIZE")
1214505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier      return ParseIntelOperator(Start, IOK_SIZE);
1215505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier    if (AsmTokStr == "type" || AsmTokStr == "TYPE")
1216505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier      return ParseIntelOperator(Start, IOK_TYPE);
1217505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier  }
1218505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier
1219505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier  // Immediate.
1220d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  if (getLexer().is(AsmToken::Integer) || getLexer().is(AsmToken::Real) ||
1221d37ad247cc04c2a436e537767ac1aec709901594Devang Patel      getLexer().is(AsmToken::Minus)) {
1222d37ad247cc04c2a436e537767ac1aec709901594Devang Patel    const MCExpr *Val;
1223d37ad247cc04c2a436e537767ac1aec709901594Devang Patel    if (!getParser().ParseExpression(Val, End)) {
1224d37ad247cc04c2a436e537767ac1aec709901594Devang Patel      return X86Operand::CreateImm(Val, Start, End);
1225d37ad247cc04c2a436e537767ac1aec709901594Devang Patel    }
1226d37ad247cc04c2a436e537767ac1aec709901594Devang Patel  }
1227d37ad247cc04c2a436e537767ac1aec709901594Devang Patel
1228505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier  // Register.
12291aea430b8834f7bed3a14eda5027eac2133d6496Devang Patel  unsigned RegNo = 0;
12301aea430b8834f7bed3a14eda5027eac2133d6496Devang Patel  if (!ParseRegister(RegNo, Start, End)) {
12315b0f1b37639d57dec72972fe445880a8a99d8674Chad Rosier    // If this is a segment register followed by a ':', then this is the start
12325b0f1b37639d57dec72972fe445880a8a99d8674Chad Rosier    // of a memory reference, otherwise this is a normal register reference.
12335b0f1b37639d57dec72972fe445880a8a99d8674Chad Rosier    if (getLexer().isNot(AsmToken::Colon))
12343ebe59c892051375623fea55e977ff559fdb3323Jordan Rose      return X86Operand::CreateReg(RegNo, Start, End);
12355b0f1b37639d57dec72972fe445880a8a99d8674Chad Rosier
12365b0f1b37639d57dec72972fe445880a8a99d8674Chad Rosier    getParser().Lex(); // Eat the colon.
12375b0f1b37639d57dec72972fe445880a8a99d8674Chad Rosier    return ParseIntelMemOperand(RegNo, Start);
12380a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel  }
12390a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel
1240505bca3617fe310a5ff07914e3cf3ea6ae4d27edChad Rosier  // Memory operand.
12415b0f1b37639d57dec72972fe445880a8a99d8674Chad Rosier  return ParseIntelMemOperand(0, Start);
12420a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel}
12430a338868b746f29d6d72fd95e425ec8696ed8024Devang Patel
1244dd929fc704054fa79cc1171354f95d91a5b62de2Devang PatelX86Operand *X86AsmParser::ParseATTOperand() {
124516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  switch (getLexer().getKind()) {
124616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  default:
1247eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    // Parse a memory operand with no segment register.
1248eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    return ParseMemOperand(0, Parser.getTok().getLoc());
124923075746a1418f281bc2a088ea85560bfd833599Chris Lattner  case AsmToken::Percent: {
1250eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    // Read the register.
125123075746a1418f281bc2a088ea85560bfd833599Chris Lattner    unsigned RegNo;
125229ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    SMLoc Start, End;
125329ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner    if (ParseRegister(RegNo, Start, End)) return 0;
12543c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes    if (RegNo == X86::EIZ || RegNo == X86::RIZ) {
12555efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer      Error(Start, "%eiz and %riz can only be used as index registers",
12565efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer            SMRange(Start, End));
12573c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes      return 0;
12583c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes    }
1259f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
1260eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    // If this is a segment register followed by a ':', then this is the start
1261eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    // of a memory reference, otherwise this is a normal register reference.
1262eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    if (getLexer().isNot(AsmToken::Colon))
1263eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner      return X86Operand::CreateReg(RegNo, Start, End);
1264f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
1265f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
1266eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    getParser().Lex(); // Eat the colon.
1267eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner    return ParseMemOperand(RegNo, Start);
126823075746a1418f281bc2a088ea85560bfd833599Chris Lattner  }
126916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  case AsmToken::Dollar: {
127016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // $42 -> immediate.
127118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    SMLoc Start = Parser.getTok().getLoc(), End;
1272b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
12738c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar    const MCExpr *Val;
127454482b472a888c9efe003ad694ecf47b21878f0eChris Lattner    if (getParser().ParseExpression(Val, End))
1275309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner      return 0;
1276b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner    return X86Operand::CreateImm(Val, Start, End);
127716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
127816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
127916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar}
128016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
1281eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner/// ParseMemOperand: segment: disp(basereg, indexreg, scale).  The '%ds:' prefix
1282eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner/// has already been parsed if present.
1283dd929fc704054fa79cc1171354f95d91a5b62de2Devang PatelX86Operand *X86AsmParser::ParseMemOperand(unsigned SegReg, SMLoc MemStart) {
1284f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
128516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  // We have to disambiguate a parenthesized expression "(4+5)" from the start
128616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)".  The
128775f265fbbbb64ab060bf41c5a4677ce56014ce9fChris Lattner  // only way to do this without lookahead is to eat the '(' and see what is
128875f265fbbbb64ab060bf41c5a4677ce56014ce9fChris Lattner  // after it.
12898c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar  const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext());
129016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  if (getLexer().isNot(AsmToken::LParen)) {
129154482b472a888c9efe003ad694ecf47b21878f0eChris Lattner    SMLoc ExprEnd;
129254482b472a888c9efe003ad694ecf47b21878f0eChris Lattner    if (getParser().ParseExpression(Disp, ExprEnd)) return 0;
1293f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
129416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // After parsing the base expression we could either have a parenthesized
129516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // memory address or not.  If not, return now.  If so, eat the (.
129616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    if (getLexer().isNot(AsmToken::LParen)) {
1297c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar      // Unless we have a segment register, treat this as an immediate.
1298309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner      if (SegReg == 0)
1299b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar        return X86Operand::CreateMem(Disp, MemStart, ExprEnd);
13000a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner      return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd);
130116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    }
1302f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
130316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // Eat the '('.
1304b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
130516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  } else {
130616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // Okay, we have a '('.  We don't know if this is an expression or not, but
130716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // so we have to eat the ( to see beyond it.
130818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    SMLoc LParenLoc = Parser.getTok().getLoc();
1309b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat the '('.
1310f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
13117b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby    if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) {
131216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // Nothing to do here, fall into the code below with the '(' part of the
131316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // memory operand consumed.
131416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    } else {
1315b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner      SMLoc ExprEnd;
1316f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
131716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // It must be an parenthesized expression, parse it now.
1318b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner      if (getParser().ParseParenExpression(Disp, ExprEnd))
1319309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        return 0;
1320f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
132116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // After parsing the base expression we could either have a parenthesized
132216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // memory address or not.  If not, return now.  If so, eat the (.
132316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      if (getLexer().isNot(AsmToken::LParen)) {
1324c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar        // Unless we have a segment register, treat this as an immediate.
1325309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        if (SegReg == 0)
1326b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar          return X86Operand::CreateMem(Disp, LParenLoc, ExprEnd);
13270a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner        return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd);
132816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      }
1329f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
133016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // Eat the '('.
1331b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();
133216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    }
133316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
1334f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
133516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  // If we reached here, then we just ate the ( of the memory operand.  Process
133616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  // the rest of the memory operand.
1337022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar  unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
133884faf659125cb354794e457fa5a8a8daad84760dKevin Enderby  SMLoc IndexLoc;
1339f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
134029ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner  if (getLexer().is(AsmToken::Percent)) {
13415efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer    SMLoc StartLoc, EndLoc;
13425efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer    if (ParseRegister(BaseReg, StartLoc, EndLoc)) return 0;
13433c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes    if (BaseReg == X86::EIZ || BaseReg == X86::RIZ) {
13445efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer      Error(StartLoc, "eiz and riz can only be used as index registers",
13455efabcf01d1c9cdf7ac59a17d757c6ad4cdb112cBenjamin Kramer            SMRange(StartLoc, EndLoc));
13463c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes      return 0;
13473c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes    }
134829ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner  }
1349f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
135016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  if (getLexer().is(AsmToken::Comma)) {
1351b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat the comma.
135284faf659125cb354794e457fa5a8a8daad84760dKevin Enderby    IndexLoc = Parser.getTok().getLoc();
135316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
135416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // Following the comma we should have either an index register, or a scale
135516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // value. We don't support the later form, but we want to parse it
135616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // correctly.
135716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    //
135816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // Not that even though it would be completely consistent to support syntax
13593c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes    // like "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this.
13607b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby    if (getLexer().is(AsmToken::Percent)) {
136129ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner      SMLoc L;
136229ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner      if (ParseRegister(IndexReg, L, L)) return 0;
1363f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
136416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      if (getLexer().isNot(AsmToken::RParen)) {
136516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar        // Parse the scale amount:
136616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar        //  ::= ',' [scale-expression]
1367309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        if (getLexer().isNot(AsmToken::Comma)) {
136818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan          Error(Parser.getTok().getLoc(),
1369309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner                "expected comma in scale expression");
1370309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner          return 0;
1371309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        }
1372b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan        Parser.Lex(); // Eat the comma.
137316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
137416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar        if (getLexer().isNot(AsmToken::RParen)) {
137518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan          SMLoc Loc = Parser.getTok().getLoc();
137616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
137716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar          int64_t ScaleVal;
137858dfaa14651f36fc9fce2031eb011e65ae267b9fKevin Enderby          if (getParser().ParseAbsoluteExpression(ScaleVal)){
137958dfaa14651f36fc9fce2031eb011e65ae267b9fKevin Enderby            Error(Loc, "expected scale expression");
1380309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner            return 0;
138176bd9386f1e1487a49c7c34ff95078dea20e3154Craig Topper          }
1382f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
138316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar          // Validate the scale amount.
1384309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner          if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8){
1385309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner            Error(Loc, "scale factor in address must be 1, 2, 4 or 8");
1386309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner            return 0;
1387309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner          }
138816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar          Scale = (unsigned)ScaleVal;
138916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar        }
139016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      }
139116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    } else if (getLexer().isNot(AsmToken::RParen)) {
1392ee9102587e7f6fc95de9fc5731b341eeb9bfc3caDaniel Dunbar      // A scale amount without an index is ignored.
139316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // index.
139418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan      SMLoc Loc = Parser.getTok().getLoc();
139516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
139616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      int64_t Value;
139716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      if (getParser().ParseAbsoluteExpression(Value))
1398309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        return 0;
1399f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
1400ee9102587e7f6fc95de9fc5731b341eeb9bfc3caDaniel Dunbar      if (Value != 1)
1401ee9102587e7f6fc95de9fc5731b341eeb9bfc3caDaniel Dunbar        Warning(Loc, "scale factor without index register is ignored");
1402ee9102587e7f6fc95de9fc5731b341eeb9bfc3caDaniel Dunbar      Scale = 1;
140316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    }
140416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
1405f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
140616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  // Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
1407309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner  if (getLexer().isNot(AsmToken::RParen)) {
140818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    Error(Parser.getTok().getLoc(), "unexpected token in memory operand");
1409309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner    return 0;
1410309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner  }
14113ebe59c892051375623fea55e977ff559fdb3323Jordan Rose  SMLoc MemEnd = Parser.getTok().getEndLoc();
1412b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat the ')'.
1413f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes
141484faf659125cb354794e457fa5a8a8daad84760dKevin Enderby  // If we have both a base register and an index register make sure they are
141584faf659125cb354794e457fa5a8a8daad84760dKevin Enderby  // both 64-bit or 32-bit registers.
14161f7a1b68a07ea6bdf521525a7928f4a8c5216713Manman Ren  // To support VSIB, IndexReg can be 128-bit or 256-bit registers.
141784faf659125cb354794e457fa5a8a8daad84760dKevin Enderby  if (BaseReg != 0 && IndexReg != 0) {
141884faf659125cb354794e457fa5a8a8daad84760dKevin Enderby    if (X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) &&
14191f7a1b68a07ea6bdf521525a7928f4a8c5216713Manman Ren        (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
14201f7a1b68a07ea6bdf521525a7928f4a8c5216713Manman Ren         X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg)) &&
142184faf659125cb354794e457fa5a8a8daad84760dKevin Enderby        IndexReg != X86::RIZ) {
142284faf659125cb354794e457fa5a8a8daad84760dKevin Enderby      Error(IndexLoc, "index register is 32-bit, but base register is 64-bit");
142384faf659125cb354794e457fa5a8a8daad84760dKevin Enderby      return 0;
142484faf659125cb354794e457fa5a8a8daad84760dKevin Enderby    }
142584faf659125cb354794e457fa5a8a8daad84760dKevin Enderby    if (X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg) &&
14261f7a1b68a07ea6bdf521525a7928f4a8c5216713Manman Ren        (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
14271f7a1b68a07ea6bdf521525a7928f4a8c5216713Manman Ren         X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) &&
142884faf659125cb354794e457fa5a8a8daad84760dKevin Enderby        IndexReg != X86::EIZ){
142984faf659125cb354794e457fa5a8a8daad84760dKevin Enderby      Error(IndexLoc, "index register is 64-bit, but base register is 32-bit");
143084faf659125cb354794e457fa5a8a8daad84760dKevin Enderby      return 0;
143184faf659125cb354794e457fa5a8a8daad84760dKevin Enderby    }
143284faf659125cb354794e457fa5a8a8daad84760dKevin Enderby  }
143384faf659125cb354794e457fa5a8a8daad84760dKevin Enderby
14340a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner  return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale,
14350a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner                               MemStart, MemEnd);
1436dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar}
1437dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar
1438dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patelbool X86AsmParser::
14396a020a71173a3ea7738a9df69982e85ddbfe0303Chad RosierParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
14409898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner                 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
14416a020a71173a3ea7738a9df69982e85ddbfe0303Chad Rosier  InstInfo = &Info;
1442693173feefaa326fad0e386470846fb3199ba381Chris Lattner  StringRef PatchedName = Name;
144339e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar
1444d8f717911dcdccb1a60b3049ea22c7767970dcb7Chris Lattner  // FIXME: Hack to recognize setneb as setne.
1445d8f717911dcdccb1a60b3049ea22c7767970dcb7Chris Lattner  if (PatchedName.startswith("set") && PatchedName.endswith("b") &&
1446d8f717911dcdccb1a60b3049ea22c7767970dcb7Chris Lattner      PatchedName != "setb" && PatchedName != "setnb")
1447d8f717911dcdccb1a60b3049ea22c7767970dcb7Chris Lattner    PatchedName = PatchedName.substr(0, Name.size()-1);
144836b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier
144939e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar  // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}.
145039e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar  const MCExpr *ExtraImmOp = 0;
1451428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes  if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) &&
145239e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      (PatchedName.endswith("ss") || PatchedName.endswith("sd") ||
145339e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar       PatchedName.endswith("ps") || PatchedName.endswith("pd"))) {
14549e6ddcb88ec40422c0ebd260567e2264ec424506Craig Topper    bool IsVCMP = PatchedName[0] == 'v';
1455428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes    unsigned SSECCIdx = IsVCMP ? 4 : 3;
145639e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar    unsigned SSEComparisonCode = StringSwitch<unsigned>(
1457428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes      PatchedName.slice(SSECCIdx, PatchedName.size() - 2))
14589e6ddcb88ec40422c0ebd260567e2264ec424506Craig Topper      .Case("eq",       0x00)
14599e6ddcb88ec40422c0ebd260567e2264ec424506Craig Topper      .Case("lt",       0x01)
14609e6ddcb88ec40422c0ebd260567e2264ec424506Craig Topper      .Case("le",       0x02)
14619e6ddcb88ec40422c0ebd260567e2264ec424506Craig Topper      .Case("unord",    0x03)
14629e6ddcb88ec40422c0ebd260567e2264ec424506Craig Topper      .Case("neq",      0x04)
14639e6ddcb88ec40422c0ebd260567e2264ec424506Craig Topper      .Case("nlt",      0x05)
14649e6ddcb88ec40422c0ebd260567e2264ec424506Craig Topper      .Case("nle",      0x06)
14659e6ddcb88ec40422c0ebd260567e2264ec424506Craig Topper      .Case("ord",      0x07)
14669e6ddcb88ec40422c0ebd260567e2264ec424506Craig Topper      /* AVX only from here */
14679e6ddcb88ec40422c0ebd260567e2264ec424506Craig Topper      .Case("eq_uq",    0x08)
14689e6ddcb88ec40422c0ebd260567e2264ec424506Craig Topper      .Case("nge",      0x09)
1469cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("ngt",      0x0A)
1470cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("false",    0x0B)
1471cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("neq_oq",   0x0C)
1472cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("ge",       0x0D)
1473cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("gt",       0x0E)
1474cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("true",     0x0F)
1475cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("eq_os",    0x10)
1476cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("lt_oq",    0x11)
1477cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("le_oq",    0x12)
1478cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("unord_s",  0x13)
1479cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("neq_us",   0x14)
1480cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("nlt_uq",   0x15)
1481cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("nle_uq",   0x16)
1482cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("ord_s",    0x17)
1483cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("eq_us",    0x18)
1484cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("nge_uq",   0x19)
1485cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("ngt_uq",   0x1A)
1486cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("false_os", 0x1B)
1487cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("neq_os",   0x1C)
1488cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("ge_oq",    0x1D)
1489cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("gt_oq",    0x1E)
1490cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes      .Case("true_us",  0x1F)
149139e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      .Default(~0U);
14929e6ddcb88ec40422c0ebd260567e2264ec424506Craig Topper    if (SSEComparisonCode != ~0U && (IsVCMP || SSEComparisonCode < 8)) {
149339e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      ExtraImmOp = MCConstantExpr::Create(SSEComparisonCode,
149439e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar                                          getParser().getContext());
149539e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      if (PatchedName.endswith("ss")) {
1496428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes        PatchedName = IsVCMP ? "vcmpss" : "cmpss";
149739e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      } else if (PatchedName.endswith("sd")) {
1498428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes        PatchedName = IsVCMP ? "vcmpsd" : "cmpsd";
149939e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      } else if (PatchedName.endswith("ps")) {
1500428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes        PatchedName = IsVCMP ? "vcmpps" : "cmpps";
150139e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      } else {
150239e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar        assert(PatchedName.endswith("pd") && "Unexpected mnemonic!");
1503428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes        PatchedName = IsVCMP ? "vcmppd" : "cmppd";
150439e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar      }
150539e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar    }
150639e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar  }
1507f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes
15081b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar  Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
150916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
1510885f65b4a1c1ec80cd800a0617c57a2289472165Devang Patel  if (ExtraImmOp && !isParsingIntelSyntax())
151139e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar    Operands.push_back(X86Operand::CreateImm(ExtraImmOp, NameLoc, NameLoc));
1512c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
15132544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  // Determine whether this is an instruction prefix.
15142544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  bool isPrefix =
1515693173feefaa326fad0e386470846fb3199ba381Chris Lattner    Name == "lock" || Name == "rep" ||
1516693173feefaa326fad0e386470846fb3199ba381Chris Lattner    Name == "repe" || Name == "repz" ||
1517beb6898df8f96ccea4ae147587479b507bb3e491Rafael Espindola    Name == "repne" || Name == "repnz" ||
1518bfd2d26159c87262fcf462ea442f99478a2093c9Rafael Espindola    Name == "rex64" || Name == "data16";
1519c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
1520c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
15212544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  // This does the actual operand parsing.  Don't parse any more if we have a
15222544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we
15232544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  // just want to parse the "lock" as the first instruction and the "incl" as
15242544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  // the next one.
15252544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  if (getLexer().isNot(AsmToken::EndOfStatement) && !isPrefix) {
15260db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar
15270db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar    // Parse '*' modifier.
15280db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar    if (getLexer().is(AsmToken::Star)) {
152918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan      SMLoc Loc = Parser.getTok().getLoc();
1530b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner      Operands.push_back(X86Operand::CreateToken("*", Loc));
1531b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex(); // Eat the star.
15320db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar    }
15330db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar
153416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    // Read the first operand.
1535309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner    if (X86Operand *Op = ParseOperand())
1536309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner      Operands.push_back(Op);
1537cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    else {
1538cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      Parser.EatToEndOfStatement();
153916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      return true;
1540cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    }
154139e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar
154216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    while (getLexer().is(AsmToken::Comma)) {
1543b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();  // Eat the comma.
154416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
154516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar      // Parse and remember the operand.
1546309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner      if (X86Operand *Op = ParseOperand())
1547309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner        Operands.push_back(Op);
1548cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      else {
1549cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        Parser.EatToEndOfStatement();
155016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar        return true;
1551cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      }
155216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar    }
1553c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
1554cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    if (getLexer().isNot(AsmToken::EndOfStatement)) {
1555c146c4d47a7ec54c14e730c30bea821c34dc4c48Chris Lattner      SMLoc Loc = getLexer().getLoc();
1556cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      Parser.EatToEndOfStatement();
1557c146c4d47a7ec54c14e730c30bea821c34dc4c48Chris Lattner      return Error(Loc, "unexpected token in argument list");
1558cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    }
155916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar  }
1560c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
15612544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner  if (getLexer().is(AsmToken::EndOfStatement))
15622544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner    Parser.Lex(); // Consume the EndOfStatement
156376331754d4a06e2394c15ae8f4870f4aeaf5ca1fKevin Enderby  else if (isPrefix && getLexer().is(AsmToken::Slash))
156476331754d4a06e2394c15ae8f4870f4aeaf5ca1fKevin Enderby    Parser.Lex(); // Consume the prefix separator Slash
156516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar
1566885f65b4a1c1ec80cd800a0617c57a2289472165Devang Patel  if (ExtraImmOp && isParsingIntelSyntax())
1567885f65b4a1c1ec80cd800a0617c57a2289472165Devang Patel    Operands.push_back(X86Operand::CreateImm(ExtraImmOp, NameLoc, NameLoc));
1568885f65b4a1c1ec80cd800a0617c57a2289472165Devang Patel
156998c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner  // This is a terrible hack to handle "out[bwl]? %al, (%dx)" ->
157098c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner  // "outb %al, %dx".  Out doesn't take a memory form, but this is a widely
157198c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner  // documented form in various unofficial manuals, so a lot of code uses it.
157298c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner  if ((Name == "outb" || Name == "outw" || Name == "outl" || Name == "out") &&
157398c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      Operands.size() == 3) {
157498c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner    X86Operand &Op = *(X86Operand*)Operands.back();
157598c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner    if (Op.isMem() && Op.Mem.SegReg == 0 &&
157698c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner        isa<MCConstantExpr>(Op.Mem.Disp) &&
157798c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner        cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
157898c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner        Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
157998c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      SMLoc Loc = Op.getEndLoc();
158098c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      Operands.back() = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
158198c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner      delete &Op;
158298c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner    }
158398c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner  }
158400743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger  // Same hack for "in[bwl]? (%dx), %al" -> "inb %dx, %al".
158500743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger  if ((Name == "inb" || Name == "inw" || Name == "inl" || Name == "in") &&
158600743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger      Operands.size() == 3) {
158700743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger    X86Operand &Op = *(X86Operand*)Operands.begin()[1];
158800743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger    if (Op.isMem() && Op.Mem.SegReg == 0 &&
158900743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger        isa<MCConstantExpr>(Op.Mem.Disp) &&
159000743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger        cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
159100743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger        Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
159200743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger      SMLoc Loc = Op.getEndLoc();
159300743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger      Operands.begin()[1] = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
159400743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger      delete &Op;
159500743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger    }
159600743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger  }
159796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  // Transform "ins[bwl] %dx, %es:(%edi)" into "ins[bwl]"
159896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  if (Name.startswith("ins") && Operands.size() == 3 &&
159996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      (Name == "insb" || Name == "insw" || Name == "insl")) {
160096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand &Op = *(X86Operand*)Operands.begin()[1];
160196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand &Op2 = *(X86Operand*)Operands.begin()[2];
160296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    if (Op.isReg() && Op.getReg() == X86::DX && isDstOp(Op2)) {
160396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      Operands.pop_back();
160496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      Operands.pop_back();
160596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      delete &Op;
160696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      delete &Op2;
160796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    }
160896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  }
160996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger
161096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  // Transform "outs[bwl] %ds:(%esi), %dx" into "out[bwl]"
161196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  if (Name.startswith("outs") && Operands.size() == 3 &&
161296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      (Name == "outsb" || Name == "outsw" || Name == "outsl")) {
161396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand &Op = *(X86Operand*)Operands.begin()[1];
161496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand &Op2 = *(X86Operand*)Operands.begin()[2];
161596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    if (isSrcOp(Op) && Op2.isReg() && Op2.getReg() == X86::DX) {
161696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      Operands.pop_back();
161796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      Operands.pop_back();
161896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      delete &Op;
161996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      delete &Op2;
162096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    }
162196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  }
162296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger
162396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  // Transform "movs[bwl] %ds:(%esi), %es:(%edi)" into "movs[bwl]"
162496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  if (Name.startswith("movs") && Operands.size() == 3 &&
162596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      (Name == "movsb" || Name == "movsw" || Name == "movsl" ||
162659ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng       (is64BitMode() && Name == "movsq"))) {
162796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand &Op = *(X86Operand*)Operands.begin()[1];
162896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand &Op2 = *(X86Operand*)Operands.begin()[2];
162996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    if (isSrcOp(Op) && isDstOp(Op2)) {
163096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      Operands.pop_back();
163196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      Operands.pop_back();
163296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      delete &Op;
163396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      delete &Op2;
163496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    }
163596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  }
163696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  // Transform "lods[bwl] %ds:(%esi),{%al,%ax,%eax,%rax}" into "lods[bwl]"
163796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  if (Name.startswith("lods") && Operands.size() == 3 &&
163896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      (Name == "lods" || Name == "lodsb" || Name == "lodsw" ||
163959ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng       Name == "lodsl" || (is64BitMode() && Name == "lodsq"))) {
164096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]);
164196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand *Op2 = static_cast<X86Operand*>(Operands[2]);
164296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    if (isSrcOp(*Op1) && Op2->isReg()) {
164396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      const char *ins;
164496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      unsigned reg = Op2->getReg();
164596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      bool isLods = Name == "lods";
164696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      if (reg == X86::AL && (isLods || Name == "lodsb"))
164796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = "lodsb";
164896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      else if (reg == X86::AX && (isLods || Name == "lodsw"))
164996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = "lodsw";
165096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      else if (reg == X86::EAX && (isLods || Name == "lodsl"))
165196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = "lodsl";
165296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      else if (reg == X86::RAX && (isLods || Name == "lodsq"))
165396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = "lodsq";
165496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      else
165596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = NULL;
165696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      if (ins != NULL) {
165796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        Operands.pop_back();
165896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        Operands.pop_back();
165996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        delete Op1;
166096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        delete Op2;
166196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        if (Name != ins)
166296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger          static_cast<X86Operand*>(Operands[0])->setTokenValue(ins);
166396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      }
166496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    }
166596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  }
166696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  // Transform "stos[bwl] {%al,%ax,%eax,%rax},%es:(%edi)" into "stos[bwl]"
166796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  if (Name.startswith("stos") && Operands.size() == 3 &&
166896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      (Name == "stos" || Name == "stosb" || Name == "stosw" ||
166959ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng       Name == "stosl" || (is64BitMode() && Name == "stosq"))) {
167096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]);
167196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    X86Operand *Op2 = static_cast<X86Operand*>(Operands[2]);
167296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    if (isDstOp(*Op2) && Op1->isReg()) {
167396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      const char *ins;
167496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      unsigned reg = Op1->getReg();
167596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      bool isStos = Name == "stos";
167696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      if (reg == X86::AL && (isStos || Name == "stosb"))
167796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = "stosb";
167896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      else if (reg == X86::AX && (isStos || Name == "stosw"))
167996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = "stosw";
168096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      else if (reg == X86::EAX && (isStos || Name == "stosl"))
168196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = "stosl";
168296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      else if (reg == X86::RAX && (isStos || Name == "stosq"))
168396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = "stosq";
168496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      else
168596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        ins = NULL;
168696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      if (ins != NULL) {
168796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        Operands.pop_back();
168896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        Operands.pop_back();
168996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        delete Op1;
169096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        delete Op2;
169196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger        if (Name != ins)
169296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger          static_cast<X86Operand*>(Operands[0])->setTokenValue(ins);
169396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger      }
169496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger    }
169596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger  }
169696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger
1697e9e16a36d9ff355dab60e4b95673bf7a0cd27e86Chris Lattner  // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>.  Canonicalize to
1698ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner  // "shift <op>".
1699d5e7705a05947e60806b795880f09757e835f590Daniel Dunbar  if ((Name.startswith("shr") || Name.startswith("sar") ||
17008c24b0c6996a8f03ff32766f0695dcf19577af59Chris Lattner       Name.startswith("shl") || Name.startswith("sal") ||
17018c24b0c6996a8f03ff32766f0695dcf19577af59Chris Lattner       Name.startswith("rcl") || Name.startswith("rcr") ||
17028c24b0c6996a8f03ff32766f0695dcf19577af59Chris Lattner       Name.startswith("rol") || Name.startswith("ror")) &&
170347ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner      Operands.size() == 3) {
1704be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel    if (isParsingIntelSyntax()) {
17053b96e1fe3b695e6d845668ea90d75016f0f46a17Devang Patel      // Intel syntax
17063b96e1fe3b695e6d845668ea90d75016f0f46a17Devang Patel      X86Operand *Op1 = static_cast<X86Operand*>(Operands[2]);
17073b96e1fe3b695e6d845668ea90d75016f0f46a17Devang Patel      if (Op1->isImm() && isa<MCConstantExpr>(Op1->getImm()) &&
170876bd9386f1e1487a49c7c34ff95078dea20e3154Craig Topper          cast<MCConstantExpr>(Op1->getImm())->getValue() == 1) {
170976bd9386f1e1487a49c7c34ff95078dea20e3154Craig Topper        delete Operands[2];
171076bd9386f1e1487a49c7c34ff95078dea20e3154Craig Topper        Operands.pop_back();
17113b96e1fe3b695e6d845668ea90d75016f0f46a17Devang Patel      }
17123b96e1fe3b695e6d845668ea90d75016f0f46a17Devang Patel    } else {
17133b96e1fe3b695e6d845668ea90d75016f0f46a17Devang Patel      X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]);
17143b96e1fe3b695e6d845668ea90d75016f0f46a17Devang Patel      if (Op1->isImm() && isa<MCConstantExpr>(Op1->getImm()) &&
171576bd9386f1e1487a49c7c34ff95078dea20e3154Craig Topper          cast<MCConstantExpr>(Op1->getImm())->getValue() == 1) {
171676bd9386f1e1487a49c7c34ff95078dea20e3154Craig Topper        delete Operands[1];
171776bd9386f1e1487a49c7c34ff95078dea20e3154Craig Topper        Operands.erase(Operands.begin() + 1);
17183b96e1fe3b695e6d845668ea90d75016f0f46a17Devang Patel      }
171947ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner    }
1720f2de13f8d7bed958538bbd9dbeb9b15ea48456ccDaniel Dunbar  }
172136b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier
172215f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner  // Transforms "int $3" into "int3" as a size optimization.  We can't write an
172315f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner  // instalias with an immediate operand yet.
172415f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner  if (Name == "int" && Operands.size() == 2) {
172515f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner    X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]);
172615f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner    if (Op1->isImm() && isa<MCConstantExpr>(Op1->getImm()) &&
172715f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner        cast<MCConstantExpr>(Op1->getImm())->getValue() == 3) {
172815f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner      delete Operands[1];
172915f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner      Operands.erase(Operands.begin() + 1);
173015f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner      static_cast<X86Operand*>(Operands[0])->setTokenValue("int3");
173115f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner    }
173215f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner  }
1733c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
17349898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner  return false;
1735a3af370dc12f6d5100da5d614ab0a62da135569aDaniel Dunbar}
1736a3af370dc12f6d5100da5d614ab0a62da135569aDaniel Dunbar
1737dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patelbool X86AsmParser::
1738b8ba13f0096b560ee618512019ca86969a9fa772Devang PatelprocessInstruction(MCInst &Inst,
1739b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel                   const SmallVectorImpl<MCParsedAsmOperand*> &Ops) {
1740b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel  switch (Inst.getOpcode()) {
1741b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel  default: return false;
1742b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel  case X86::AND16i16: {
1743b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    if (!Inst.getOperand(0).isImm() ||
1744b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel        !isImmSExti16i8Value(Inst.getOperand(0).getImm()))
1745b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel      return false;
1746b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel
1747b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    MCInst TmpInst;
1748b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    TmpInst.setOpcode(X86::AND16ri8);
1749b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::AX));
1750b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::AX));
1751b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    TmpInst.addOperand(Inst.getOperand(0));
1752b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    Inst = TmpInst;
1753b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    return true;
1754b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel  }
1755b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel  case X86::AND32i32: {
1756b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    if (!Inst.getOperand(0).isImm() ||
1757b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel        !isImmSExti32i8Value(Inst.getOperand(0).getImm()))
1758b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel      return false;
1759b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel
1760b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    MCInst TmpInst;
1761b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    TmpInst.setOpcode(X86::AND32ri8);
1762b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::EAX));
1763b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::EAX));
1764b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    TmpInst.addOperand(Inst.getOperand(0));
1765b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    Inst = TmpInst;
1766b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    return true;
1767b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel  }
1768b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel  case X86::AND64i32: {
1769b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    if (!Inst.getOperand(0).isImm() ||
1770b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel        !isImmSExti64i8Value(Inst.getOperand(0).getImm()))
1771b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel      return false;
1772b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel
1773b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    MCInst TmpInst;
1774b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    TmpInst.setOpcode(X86::AND64ri8);
1775b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::RAX));
1776b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::RAX));
1777b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    TmpInst.addOperand(Inst.getOperand(0));
1778b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    Inst = TmpInst;
1779b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    return true;
1780b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel  }
1781ac0f0486022fb1798579c9a550154e839770efa9Devang Patel  case X86::XOR16i16: {
1782ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    if (!Inst.getOperand(0).isImm() ||
1783ac0f0486022fb1798579c9a550154e839770efa9Devang Patel        !isImmSExti16i8Value(Inst.getOperand(0).getImm()))
1784ac0f0486022fb1798579c9a550154e839770efa9Devang Patel      return false;
1785ac0f0486022fb1798579c9a550154e839770efa9Devang Patel
1786ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    MCInst TmpInst;
1787ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.setOpcode(X86::XOR16ri8);
1788ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::AX));
1789ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::AX));
1790ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(Inst.getOperand(0));
1791ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    Inst = TmpInst;
1792ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    return true;
1793ac0f0486022fb1798579c9a550154e839770efa9Devang Patel  }
1794ac0f0486022fb1798579c9a550154e839770efa9Devang Patel  case X86::XOR32i32: {
1795ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    if (!Inst.getOperand(0).isImm() ||
1796ac0f0486022fb1798579c9a550154e839770efa9Devang Patel        !isImmSExti32i8Value(Inst.getOperand(0).getImm()))
1797ac0f0486022fb1798579c9a550154e839770efa9Devang Patel      return false;
1798ac0f0486022fb1798579c9a550154e839770efa9Devang Patel
1799ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    MCInst TmpInst;
1800ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.setOpcode(X86::XOR32ri8);
1801ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::EAX));
1802ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::EAX));
1803ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(Inst.getOperand(0));
1804ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    Inst = TmpInst;
1805ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    return true;
1806ac0f0486022fb1798579c9a550154e839770efa9Devang Patel  }
1807ac0f0486022fb1798579c9a550154e839770efa9Devang Patel  case X86::XOR64i32: {
1808ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    if (!Inst.getOperand(0).isImm() ||
1809ac0f0486022fb1798579c9a550154e839770efa9Devang Patel        !isImmSExti64i8Value(Inst.getOperand(0).getImm()))
1810ac0f0486022fb1798579c9a550154e839770efa9Devang Patel      return false;
1811ac0f0486022fb1798579c9a550154e839770efa9Devang Patel
1812ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    MCInst TmpInst;
1813ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.setOpcode(X86::XOR64ri8);
1814ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::RAX));
1815ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::RAX));
1816ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(Inst.getOperand(0));
1817ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    Inst = TmpInst;
1818ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    return true;
1819ac0f0486022fb1798579c9a550154e839770efa9Devang Patel  }
1820ac0f0486022fb1798579c9a550154e839770efa9Devang Patel  case X86::OR16i16: {
1821ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    if (!Inst.getOperand(0).isImm() ||
1822ac0f0486022fb1798579c9a550154e839770efa9Devang Patel        !isImmSExti16i8Value(Inst.getOperand(0).getImm()))
1823ac0f0486022fb1798579c9a550154e839770efa9Devang Patel      return false;
1824ac0f0486022fb1798579c9a550154e839770efa9Devang Patel
1825ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    MCInst TmpInst;
1826ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.setOpcode(X86::OR16ri8);
1827ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::AX));
1828ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::AX));
1829ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(Inst.getOperand(0));
1830ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    Inst = TmpInst;
1831ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    return true;
1832ac0f0486022fb1798579c9a550154e839770efa9Devang Patel  }
1833ac0f0486022fb1798579c9a550154e839770efa9Devang Patel  case X86::OR32i32: {
1834ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    if (!Inst.getOperand(0).isImm() ||
1835ac0f0486022fb1798579c9a550154e839770efa9Devang Patel        !isImmSExti32i8Value(Inst.getOperand(0).getImm()))
1836ac0f0486022fb1798579c9a550154e839770efa9Devang Patel      return false;
1837ac0f0486022fb1798579c9a550154e839770efa9Devang Patel
1838ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    MCInst TmpInst;
1839ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.setOpcode(X86::OR32ri8);
1840ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::EAX));
1841ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::EAX));
1842ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(Inst.getOperand(0));
1843ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    Inst = TmpInst;
1844ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    return true;
1845ac0f0486022fb1798579c9a550154e839770efa9Devang Patel  }
1846ac0f0486022fb1798579c9a550154e839770efa9Devang Patel  case X86::OR64i32: {
1847ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    if (!Inst.getOperand(0).isImm() ||
1848ac0f0486022fb1798579c9a550154e839770efa9Devang Patel        !isImmSExti64i8Value(Inst.getOperand(0).getImm()))
1849ac0f0486022fb1798579c9a550154e839770efa9Devang Patel      return false;
1850ac0f0486022fb1798579c9a550154e839770efa9Devang Patel
1851ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    MCInst TmpInst;
1852ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.setOpcode(X86::OR64ri8);
1853ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::RAX));
1854ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::RAX));
1855ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(Inst.getOperand(0));
1856ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    Inst = TmpInst;
1857ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    return true;
1858ac0f0486022fb1798579c9a550154e839770efa9Devang Patel  }
1859ac0f0486022fb1798579c9a550154e839770efa9Devang Patel  case X86::CMP16i16: {
1860ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    if (!Inst.getOperand(0).isImm() ||
1861ac0f0486022fb1798579c9a550154e839770efa9Devang Patel        !isImmSExti16i8Value(Inst.getOperand(0).getImm()))
1862ac0f0486022fb1798579c9a550154e839770efa9Devang Patel      return false;
1863ac0f0486022fb1798579c9a550154e839770efa9Devang Patel
1864ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    MCInst TmpInst;
1865ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.setOpcode(X86::CMP16ri8);
1866ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::AX));
1867ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(Inst.getOperand(0));
1868ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    Inst = TmpInst;
1869ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    return true;
1870ac0f0486022fb1798579c9a550154e839770efa9Devang Patel  }
1871ac0f0486022fb1798579c9a550154e839770efa9Devang Patel  case X86::CMP32i32: {
1872ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    if (!Inst.getOperand(0).isImm() ||
1873ac0f0486022fb1798579c9a550154e839770efa9Devang Patel        !isImmSExti32i8Value(Inst.getOperand(0).getImm()))
1874ac0f0486022fb1798579c9a550154e839770efa9Devang Patel      return false;
1875ac0f0486022fb1798579c9a550154e839770efa9Devang Patel
1876ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    MCInst TmpInst;
1877ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.setOpcode(X86::CMP32ri8);
1878ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::EAX));
1879ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(Inst.getOperand(0));
1880ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    Inst = TmpInst;
1881ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    return true;
1882ac0f0486022fb1798579c9a550154e839770efa9Devang Patel  }
1883ac0f0486022fb1798579c9a550154e839770efa9Devang Patel  case X86::CMP64i32: {
1884ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    if (!Inst.getOperand(0).isImm() ||
1885ac0f0486022fb1798579c9a550154e839770efa9Devang Patel        !isImmSExti64i8Value(Inst.getOperand(0).getImm()))
1886ac0f0486022fb1798579c9a550154e839770efa9Devang Patel      return false;
1887ac0f0486022fb1798579c9a550154e839770efa9Devang Patel
1888ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    MCInst TmpInst;
1889ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.setOpcode(X86::CMP64ri8);
1890ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::RAX));
1891ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    TmpInst.addOperand(Inst.getOperand(0));
1892ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    Inst = TmpInst;
1893ac0f0486022fb1798579c9a550154e839770efa9Devang Patel    return true;
1894ac0f0486022fb1798579c9a550154e839770efa9Devang Patel  }
1895a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel  case X86::ADD16i16: {
1896a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    if (!Inst.getOperand(0).isImm() ||
1897a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel        !isImmSExti16i8Value(Inst.getOperand(0).getImm()))
1898a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel      return false;
1899a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel
1900a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    MCInst TmpInst;
1901a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.setOpcode(X86::ADD16ri8);
1902a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::AX));
1903a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::AX));
1904a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.addOperand(Inst.getOperand(0));
1905a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    Inst = TmpInst;
1906a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    return true;
1907a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel  }
1908a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel  case X86::ADD32i32: {
1909a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    if (!Inst.getOperand(0).isImm() ||
1910a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel        !isImmSExti32i8Value(Inst.getOperand(0).getImm()))
1911a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel      return false;
1912a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel
1913a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    MCInst TmpInst;
1914a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.setOpcode(X86::ADD32ri8);
1915a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::EAX));
1916a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::EAX));
1917a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.addOperand(Inst.getOperand(0));
1918a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    Inst = TmpInst;
1919a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    return true;
1920a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel  }
1921a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel  case X86::ADD64i32: {
1922a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    if (!Inst.getOperand(0).isImm() ||
1923a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel        !isImmSExti64i8Value(Inst.getOperand(0).getImm()))
1924a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel      return false;
1925a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel
1926a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    MCInst TmpInst;
1927a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.setOpcode(X86::ADD64ri8);
1928a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::RAX));
1929a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::RAX));
1930a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.addOperand(Inst.getOperand(0));
1931a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    Inst = TmpInst;
1932a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    return true;
1933a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel  }
1934a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel  case X86::SUB16i16: {
1935a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    if (!Inst.getOperand(0).isImm() ||
1936a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel        !isImmSExti16i8Value(Inst.getOperand(0).getImm()))
1937a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel      return false;
1938a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel
1939a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    MCInst TmpInst;
1940a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.setOpcode(X86::SUB16ri8);
1941a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::AX));
1942a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::AX));
1943a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.addOperand(Inst.getOperand(0));
1944a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    Inst = TmpInst;
1945a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    return true;
1946a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel  }
1947a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel  case X86::SUB32i32: {
1948a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    if (!Inst.getOperand(0).isImm() ||
1949a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel        !isImmSExti32i8Value(Inst.getOperand(0).getImm()))
1950a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel      return false;
1951a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel
1952a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    MCInst TmpInst;
1953a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.setOpcode(X86::SUB32ri8);
1954a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::EAX));
1955a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::EAX));
1956a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.addOperand(Inst.getOperand(0));
1957a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    Inst = TmpInst;
1958a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    return true;
1959a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel  }
1960a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel  case X86::SUB64i32: {
1961a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    if (!Inst.getOperand(0).isImm() ||
1962a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel        !isImmSExti64i8Value(Inst.getOperand(0).getImm()))
1963a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel      return false;
1964a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel
1965a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    MCInst TmpInst;
1966a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.setOpcode(X86::SUB64ri8);
1967a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::RAX));
1968a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.addOperand(MCOperand::CreateReg(X86::RAX));
1969a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    TmpInst.addOperand(Inst.getOperand(0));
1970a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    Inst = TmpInst;
1971a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel    return true;
1972a951f77ca31b43551bd41765504519d6d76e6cbfDevang Patel  }
1973b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel  }
1974b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel}
1975b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel
19763ca6382120c16e30151e19175d40480ee72de641Jim Grosbachstatic const char *getSubtargetFeatureName(unsigned Val);
1977b8ba13f0096b560ee618512019ca86969a9fa772Devang Patelbool X86AsmParser::
197884125ca43c758fd21fdab2b05196e0df57c55c96Chad RosierMatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
19797c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner                        SmallVectorImpl<MCParsedAsmOperand*> &Operands,
198084125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier                        MCStreamer &Out, unsigned &ErrorInfo,
198184125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier                        bool MatchingInlineAsm) {
1982f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar  assert(!Operands.empty() && "Unexpect empty operand list!");
19837c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner  X86Operand *Op = static_cast<X86Operand*>(Operands[0]);
19847c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner  assert(Op->isToken() && "Leading operand should always be a mnemonic!");
1985b4fdadef51ed254d9282356463c6b11ff8a102dfChad Rosier  ArrayRef<SMRange> EmptyRanges = ArrayRef<SMRange>();
19867c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner
19877c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner  // First, handle aliases that expand to multiple instructions.
19887c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner  // FIXME: This should be replaced with a real .td file alias mechanism.
19894ee0808d9f1c7d64b0b304e610ce0fb496dd3279Chad Rosier  // Also, MatchInstructionImpl should actually *do* the EmitInstruction
199090fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner  // call.
19910966ec08610c02c8556105f2fff88a7e7247a549Andrew Trick  if (Op->getToken() == "fstsw" || Op->getToken() == "fstcw" ||
19928b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner      Op->getToken() == "fstsww" || Op->getToken() == "fstcww" ||
1993905f2e06691672c236ae864faf0ad7220afc2844Chris Lattner      Op->getToken() == "finit" || Op->getToken() == "fsave" ||
19945a378076a44ef3f507b91aa8e7715fabaec42074Kevin Enderby      Op->getToken() == "fstenv" || Op->getToken() == "fclex") {
19957c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner    MCInst Inst;
19967c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner    Inst.setOpcode(X86::WAIT);
1997cb5dca38157a48c734660746e7f7340d5db7c2dbJim Grosbach    Inst.setLoc(IDLoc);
19987a2b624bb34374fe233f71cc5220d5ae0a0971cfChad Rosier    if (!MatchingInlineAsm)
199922685876ed7231f32f7d1698c00acab22825b74cChad Rosier      Out.EmitInstruction(Inst);
2000f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar
20010bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner    const char *Repl =
20020bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner      StringSwitch<const char*>(Op->getToken())
20038b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner        .Case("finit",  "fninit")
20048b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner        .Case("fsave",  "fnsave")
20058b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner        .Case("fstcw",  "fnstcw")
20068b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner        .Case("fstcww",  "fnstcw")
2007905f2e06691672c236ae864faf0ad7220afc2844Chris Lattner        .Case("fstenv", "fnstenv")
20088b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner        .Case("fstsw",  "fnstsw")
20098b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner        .Case("fstsww", "fnstsw")
20108b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner        .Case("fclex",  "fnclex")
20110bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner        .Default(0);
20120bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner    assert(Repl && "Unknown wait-prefixed instruction");
2013b0f96facd6e6637cb71bbeaf2f4e006f0b6348e3Benjamin Kramer    delete Operands[0];
20140bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner    Operands[0] = X86Operand::CreateToken(Repl, IDLoc);
20157c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner  }
2016c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
2017a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  bool WasOriginallyInvalidOperand = false;
20187036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner  MCInst Inst;
2019c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
2020c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // First, try a direct match.
20216e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier  switch (MatchInstructionImpl(Operands, Inst,
202284125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier                               ErrorInfo, MatchingInlineAsm,
2023be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel                               isParsingIntelSyntax())) {
202419cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  default: break;
2025ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  case Match_Success:
2026b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    // Some instructions need post-processing to, for example, tweak which
2027b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel    // encoding is selected. Loop on it while changes happen so the
202836b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier    // individual transformations can chain off each other.
20297a2b624bb34374fe233f71cc5220d5ae0a0971cfChad Rosier    if (!MatchingInlineAsm)
203022685876ed7231f32f7d1698c00acab22825b74cChad Rosier      while (processInstruction(Inst, Operands))
203122685876ed7231f32f7d1698c00acab22825b74cChad Rosier        ;
2032b8ba13f0096b560ee618512019ca86969a9fa772Devang Patel
2033cb5dca38157a48c734660746e7f7340d5db7c2dbJim Grosbach    Inst.setLoc(IDLoc);
20347a2b624bb34374fe233f71cc5220d5ae0a0971cfChad Rosier    if (!MatchingInlineAsm)
203522685876ed7231f32f7d1698c00acab22825b74cChad Rosier      Out.EmitInstruction(Inst);
203622685876ed7231f32f7d1698c00acab22825b74cChad Rosier    Opcode = Inst.getOpcode();
2037c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar    return false;
20383ca6382120c16e30151e19175d40480ee72de641Jim Grosbach  case Match_MissingFeature: {
20393ca6382120c16e30151e19175d40480ee72de641Jim Grosbach    assert(ErrorInfo && "Unknown missing feature!");
20403ca6382120c16e30151e19175d40480ee72de641Jim Grosbach    // Special case the error message for the very common case where only
20413ca6382120c16e30151e19175d40480ee72de641Jim Grosbach    // a single subtarget feature is missing.
20423ca6382120c16e30151e19175d40480ee72de641Jim Grosbach    std::string Msg = "instruction requires:";
20433ca6382120c16e30151e19175d40480ee72de641Jim Grosbach    unsigned Mask = 1;
20443ca6382120c16e30151e19175d40480ee72de641Jim Grosbach    for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
20453ca6382120c16e30151e19175d40480ee72de641Jim Grosbach      if (ErrorInfo & Mask) {
20463ca6382120c16e30151e19175d40480ee72de641Jim Grosbach        Msg += " ";
20473ca6382120c16e30151e19175d40480ee72de641Jim Grosbach        Msg += getSubtargetFeatureName(ErrorInfo & Mask);
20483ca6382120c16e30151e19175d40480ee72de641Jim Grosbach      }
20493ca6382120c16e30151e19175d40480ee72de641Jim Grosbach      Mask <<= 1;
20503ca6382120c16e30151e19175d40480ee72de641Jim Grosbach    }
20513ca6382120c16e30151e19175d40480ee72de641Jim Grosbach    return Error(IDLoc, Msg, EmptyRanges, MatchingInlineAsm);
20523ca6382120c16e30151e19175d40480ee72de641Jim Grosbach  }
2053a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  case Match_InvalidOperand:
2054a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner    WasOriginallyInvalidOperand = true;
2055a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner    break;
2056a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  case Match_MnemonicFail:
2057ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    break;
2058ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  }
2059c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
2060c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // FIXME: Ideally, we would only attempt suffix matches for things which are
2061c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // valid prefixes, and we could just infer the right unambiguous
2062c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // type. However, that requires substantially more matcher support than the
2063c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // following hack.
2064c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
2065c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // Change the operand to point to a temporary token.
2066c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  StringRef Base = Op->getToken();
2067f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar  SmallString<16> Tmp;
2068f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar  Tmp += Base;
2069f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar  Tmp += ' ';
2070f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar  Op->setTokenValue(Tmp.str());
2071c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
2072fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  // If this instruction starts with an 'f', then it is a floating point stack
2073fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  // instruction.  These come in up to three forms for 32-bit, 64-bit, and
2074fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  // 80-bit floating point, which use the suffixes s,l,t respectively.
2075fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  //
2076fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  // Otherwise, we assume that this may be an integer instruction, which comes
2077fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  // in 8/16/32/64-bit forms using the b,w,l,q suffixes respectively.
2078fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0";
207936b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier
2080c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // Check for the various suffix matches.
2081fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  Tmp[Base.size()] = Suffixes[0];
2082fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  unsigned ErrorInfoIgnore;
20833ca6382120c16e30151e19175d40480ee72de641Jim Grosbach  unsigned ErrorInfoMissingFeature;
208419cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  unsigned Match1, Match2, Match3, Match4;
208536b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier
20866e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier  Match1 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
20876e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier                                isParsingIntelSyntax());
20883ca6382120c16e30151e19175d40480ee72de641Jim Grosbach  // If this returned as a missing feature failure, remember that.
20893ca6382120c16e30151e19175d40480ee72de641Jim Grosbach  if (Match1 == Match_MissingFeature)
20903ca6382120c16e30151e19175d40480ee72de641Jim Grosbach    ErrorInfoMissingFeature = ErrorInfoIgnore;
2091fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  Tmp[Base.size()] = Suffixes[1];
20926e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier  Match2 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
20936e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier                                isParsingIntelSyntax());
20943ca6382120c16e30151e19175d40480ee72de641Jim Grosbach  // If this returned as a missing feature failure, remember that.
20953ca6382120c16e30151e19175d40480ee72de641Jim Grosbach  if (Match2 == Match_MissingFeature)
20963ca6382120c16e30151e19175d40480ee72de641Jim Grosbach    ErrorInfoMissingFeature = ErrorInfoIgnore;
2097fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  Tmp[Base.size()] = Suffixes[2];
20986e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier  Match3 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
20996e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier                                isParsingIntelSyntax());
21003ca6382120c16e30151e19175d40480ee72de641Jim Grosbach  // If this returned as a missing feature failure, remember that.
21013ca6382120c16e30151e19175d40480ee72de641Jim Grosbach  if (Match3 == Match_MissingFeature)
21023ca6382120c16e30151e19175d40480ee72de641Jim Grosbach    ErrorInfoMissingFeature = ErrorInfoIgnore;
2103fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  Tmp[Base.size()] = Suffixes[3];
21046e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier  Match4 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
21056e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier                                isParsingIntelSyntax());
21063ca6382120c16e30151e19175d40480ee72de641Jim Grosbach  // If this returned as a missing feature failure, remember that.
21073ca6382120c16e30151e19175d40480ee72de641Jim Grosbach  if (Match4 == Match_MissingFeature)
21083ca6382120c16e30151e19175d40480ee72de641Jim Grosbach    ErrorInfoMissingFeature = ErrorInfoIgnore;
2109c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
2110c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // Restore the old token.
2111c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  Op->setTokenValue(Base);
2112c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
2113c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // If exactly one matched, then we treat that as a successful match (and the
2114c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // instruction will already have been filled in correctly, since the failing
2115c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  // matches won't have modified it).
2116ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  unsigned NumSuccessfulMatches =
2117fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner    (Match1 == Match_Success) + (Match2 == Match_Success) +
2118fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner    (Match3 == Match_Success) + (Match4 == Match_Success);
21197036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner  if (NumSuccessfulMatches == 1) {
2120cb5dca38157a48c734660746e7f7340d5db7c2dbJim Grosbach    Inst.setLoc(IDLoc);
21217a2b624bb34374fe233f71cc5220d5ae0a0971cfChad Rosier    if (!MatchingInlineAsm)
212222685876ed7231f32f7d1698c00acab22825b74cChad Rosier      Out.EmitInstruction(Inst);
212322685876ed7231f32f7d1698c00acab22825b74cChad Rosier    Opcode = Inst.getOpcode();
2124c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar    return false;
21257036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner  }
2126c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
2127ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  // Otherwise, the match failed, try to produce a decent error message.
2128f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar
212909062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar  // If we had multiple suffix matches, then identify this as an ambiguous
213009062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar  // match.
2131ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  if (NumSuccessfulMatches > 1) {
213209062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    char MatchChars[4];
213309062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    unsigned NumMatches = 0;
2134fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner    if (Match1 == Match_Success) MatchChars[NumMatches++] = Suffixes[0];
2135fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner    if (Match2 == Match_Success) MatchChars[NumMatches++] = Suffixes[1];
2136fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner    if (Match3 == Match_Success) MatchChars[NumMatches++] = Suffixes[2];
2137fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner    if (Match4 == Match_Success) MatchChars[NumMatches++] = Suffixes[3];
213809062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar
213909062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    SmallString<126> Msg;
214009062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    raw_svector_ostream OS(Msg);
214109062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    OS << "ambiguous instructions require an explicit suffix (could be ";
214209062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    for (unsigned i = 0; i != NumMatches; ++i) {
214309062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar      if (i != 0)
214409062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar        OS << ", ";
214509062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar      if (i + 1 == NumMatches)
214609062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar        OS << "or ";
214709062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar      OS << "'" << Base << MatchChars[i] << "'";
214809062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    }
214909062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar    OS << ")";
21507a2b624bb34374fe233f71cc5220d5ae0a0971cfChad Rosier    Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
2151ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner    return true;
215209062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar  }
2153c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
2154a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  // Okay, we know that none of the variants matched successfully.
2155c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
2156a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  // If all of the instructions reported an invalid mnemonic, then the original
2157a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  // mnemonic was invalid.
2158fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  if ((Match1 == Match_MnemonicFail) && (Match2 == Match_MnemonicFail) &&
2159fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner      (Match3 == Match_MnemonicFail) && (Match4 == Match_MnemonicFail)) {
2160ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner    if (!WasOriginallyInvalidOperand) {
21617a2b624bb34374fe233f71cc5220d5ae0a0971cfChad Rosier      ArrayRef<SMRange> Ranges = MatchingInlineAsm ? EmptyRanges :
2162674101e6bb3742ae743e21e9b9ebec5946b1d273Chad Rosier        Op->getLocRange();
2163f82edaffb1a6d41bc89d86c69f53962e63621aadBenjamin Kramer      return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'",
21647a2b624bb34374fe233f71cc5220d5ae0a0971cfChad Rosier                   Ranges, MatchingInlineAsm);
2165ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner    }
2166ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner
2167ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner    // Recover location info for the operand if we know which was the problem.
216884125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier    if (ErrorInfo != ~0U) {
216984125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier      if (ErrorInfo >= Operands.size())
2170b4fdadef51ed254d9282356463c6b11ff8a102dfChad Rosier        return Error(IDLoc, "too few operands for instruction",
21717a2b624bb34374fe233f71cc5220d5ae0a0971cfChad Rosier                     EmptyRanges, MatchingInlineAsm);
2172c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
217384125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier      X86Operand *Operand = (X86Operand*)Operands[ErrorInfo];
2174d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner      if (Operand->getStartLoc().isValid()) {
2175d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner        SMRange OperandRange = Operand->getLocRange();
2176d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner        return Error(Operand->getStartLoc(), "invalid operand for instruction",
21777a2b624bb34374fe233f71cc5220d5ae0a0971cfChad Rosier                     OperandRange, MatchingInlineAsm);
2178d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner      }
2179ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner    }
2180ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner
2181b4fdadef51ed254d9282356463c6b11ff8a102dfChad Rosier    return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
21827a2b624bb34374fe233f71cc5220d5ae0a0971cfChad Rosier                 MatchingInlineAsm);
2183a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  }
2184c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
2185ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  // If one instruction matched with a missing feature, report this as a
2186ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  // missing feature.
2187fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  if ((Match1 == Match_MissingFeature) + (Match2 == Match_MissingFeature) +
2188fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner      (Match3 == Match_MissingFeature) + (Match4 == Match_MissingFeature) == 1){
21893ca6382120c16e30151e19175d40480ee72de641Jim Grosbach    std::string Msg = "instruction requires:";
21903ca6382120c16e30151e19175d40480ee72de641Jim Grosbach    unsigned Mask = 1;
21913ca6382120c16e30151e19175d40480ee72de641Jim Grosbach    for (unsigned i = 0; i < (sizeof(ErrorInfoMissingFeature)*8-1); ++i) {
21923ca6382120c16e30151e19175d40480ee72de641Jim Grosbach      if (ErrorInfoMissingFeature & Mask) {
21933ca6382120c16e30151e19175d40480ee72de641Jim Grosbach        Msg += " ";
21943ca6382120c16e30151e19175d40480ee72de641Jim Grosbach        Msg += getSubtargetFeatureName(ErrorInfoMissingFeature & Mask);
21953ca6382120c16e30151e19175d40480ee72de641Jim Grosbach      }
21963ca6382120c16e30151e19175d40480ee72de641Jim Grosbach      Mask <<= 1;
21973ca6382120c16e30151e19175d40480ee72de641Jim Grosbach    }
21983ca6382120c16e30151e19175d40480ee72de641Jim Grosbach    return Error(IDLoc, Msg, EmptyRanges, MatchingInlineAsm);
2199ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  }
2200c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
2201a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  // If one instruction matched with an invalid operand, report this as an
2202a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  // operand failure.
2203fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner  if ((Match1 == Match_InvalidOperand) + (Match2 == Match_InvalidOperand) +
2204fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner      (Match3 == Match_InvalidOperand) + (Match4 == Match_InvalidOperand) == 1){
2205b4fdadef51ed254d9282356463c6b11ff8a102dfChad Rosier    Error(IDLoc, "invalid operand for instruction", EmptyRanges,
22067a2b624bb34374fe233f71cc5220d5ae0a0971cfChad Rosier          MatchingInlineAsm);
2207a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner    return true;
2208a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner  }
2209c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer
2210ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner  // If all of these were an outright failure, report it in a useless way.
2211b4fdadef51ed254d9282356463c6b11ff8a102dfChad Rosier  Error(IDLoc, "unknown use of instruction mnemonic without a size suffix",
22127a2b624bb34374fe233f71cc5220d5ae0a0971cfChad Rosier        EmptyRanges, MatchingInlineAsm);
2213c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar  return true;
2214c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar}
2215c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
2216c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar
2217dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patelbool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
2218537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner  StringRef IDVal = DirectiveID.getIdentifier();
2219537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner  if (IDVal == ".word")
2220537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner    return ParseDirectiveWord(2, DirectiveID.getLoc());
2221bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng  else if (IDVal.startswith(".code"))
2222bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    return ParseDirectiveCode(IDVal, DirectiveID.getLoc());
22233c4ecd7dab5567017ad573769b0af484479bac6fChad Rosier  else if (IDVal.startswith(".att_syntax")) {
22243c4ecd7dab5567017ad573769b0af484479bac6fChad Rosier    getParser().setAssemblerDialect(0);
22253c4ecd7dab5567017ad573769b0af484479bac6fChad Rosier    return false;
22263c4ecd7dab5567017ad573769b0af484479bac6fChad Rosier  } else if (IDVal.startswith(".intel_syntax")) {
22270db58bfecea020ffcdfa1fc6458995371e1c3c50Devang Patel    getParser().setAssemblerDialect(1);
2228be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel    if (getLexer().isNot(AsmToken::EndOfStatement)) {
2229be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel      if(Parser.getTok().getString() == "noprefix") {
223076bd9386f1e1487a49c7c34ff95078dea20e3154Craig Topper        // FIXME : Handle noprefix
223176bd9386f1e1487a49c7c34ff95078dea20e3154Craig Topper        Parser.Lex();
2232be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel      } else
223376bd9386f1e1487a49c7c34ff95078dea20e3154Craig Topper        return true;
2234be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel    }
2235be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel    return false;
2236be3e310d5ed8717f070acc71b0f4dae28cb08c4dDevang Patel  }
2237537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner  return true;
2238537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner}
2239537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner
2240537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner/// ParseDirectiveWord
2241537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner///  ::= .word [ expression (, expression)* ]
2242dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patelbool X86AsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
2243537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2244537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner    for (;;) {
2245537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner      const MCExpr *Value;
2246537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner      if (getParser().ParseExpression(Value))
2247537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner        return true;
224836b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier
22491ced208be9cab0f994c5df9000da36bc313b2507Eric Christopher      getParser().getStreamer().EmitValue(Value, Size);
225036b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier
2251537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner      if (getLexer().is(AsmToken::EndOfStatement))
2252537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner        break;
225336b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier
2254537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner      // FIXME: Improve diagnostic.
2255537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner      if (getLexer().isNot(AsmToken::Comma))
2256537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner        return Error(L, "unexpected token in directive");
2257537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner      Parser.Lex();
2258537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner    }
2259537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner  }
226036b8fed61db8d772bf07ed828ff505ce15461bd7Chad Rosier
2261537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner  Parser.Lex();
2262537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner  return false;
2263537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner}
2264537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner
2265bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng/// ParseDirectiveCode
2266bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng///  ::= .code32 | .code64
2267dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patelbool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
2268bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng  if (IDVal == ".code32") {
2269bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    Parser.Lex();
2270bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    if (is64BitMode()) {
2271bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng      SwitchMode();
2272bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng      getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
2273bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    }
2274bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng  } else if (IDVal == ".code64") {
2275bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    Parser.Lex();
2276bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    if (!is64BitMode()) {
2277bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng      SwitchMode();
2278bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng      getParser().getStreamer().EmitAssemblerFlag(MCAF_Code64);
2279bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    }
2280bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng  } else {
2281bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    return Error(L, "unexpected directive " + IDVal);
2282bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng  }
2283537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner
2284bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng  return false;
2285bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng}
2286537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner
2287092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar// Force static initialization.
2288092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbarextern "C" void LLVMInitializeX86AsmParser() {
2289dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patel  RegisterMCAsmParser<X86AsmParser> X(TheX86_32Target);
2290dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patel  RegisterMCAsmParser<X86AsmParser> Y(TheX86_64Target);
2291092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar}
22920e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar
22930692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER
22940692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION
22953ca6382120c16e30151e19175d40480ee72de641Jim Grosbach#define GET_SUBTARGET_FEATURE_NAME
22960e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar#include "X86GenAsmMatcher.inc"
2297