X86AsmParser.cpp revision b7f689bab98777236a2bf600f299d232d246bb61
1092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar//===-- X86AsmParser.cpp - Parse X86 assembly to MCInst instructions ------===// 2092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar// 3092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar// The LLVM Compiler Infrastructure 4092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar// 5092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar// This file is distributed under the University of Illinois Open Source 6092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar// License. See LICENSE.TXT for details. 7092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar// 8092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar//===----------------------------------------------------------------------===// 9092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar 109898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner#include "llvm/Target/TargetAsmParser.h" 114cb1e13769856716261a4d315f8202bd918502c3Daniel Dunbar#include "X86.h" 1254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar#include "X86Subtarget.h" 1333d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner#include "llvm/Target/TargetRegistry.h" 1433d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner#include "llvm/Target/TargetAsmParser.h" 159c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby#include "llvm/MC/MCStreamer.h" 168c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar#include "llvm/MC/MCExpr.h" 17a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar#include "llvm/MC/MCInst.h" 18ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng#include "llvm/MC/MCSubtargetInfo.h" 19c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmLexer.h" 20c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmParser.h" 21c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCParsedAsmOperand.h" 2275ca4b94bd9dcd3952fdc237429342a2154ba142Benjamin Kramer#include "llvm/ADT/OwningPtr.h" 2333d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner#include "llvm/ADT/SmallString.h" 2433d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner#include "llvm/ADT/SmallVector.h" 2533d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner#include "llvm/ADT/StringExtras.h" 2633d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner#include "llvm/ADT/StringSwitch.h" 2733d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner#include "llvm/ADT/Twine.h" 2816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar#include "llvm/Support/SourceMgr.h" 2909062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar#include "llvm/Support/raw_ostream.h" 30ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 31ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng#define GET_SUBTARGETINFO_ENUM 32ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng#include "X86GenSubtargetInfo.inc" 33ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 34092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbarusing namespace llvm; 35092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar 36092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbarnamespace { 37c6b79ac88e52367dd2afdf03b1be81b10345c0bbBenjamin Kramerstruct X86Operand; 38092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar 3916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbarclass X86ATTAsmParser : public TargetAsmParser { 40ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng MCSubtargetInfo &STI; 4116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar MCAsmParser &Parser; 42c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer 4316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbarprivate: 4416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar MCAsmParser &getParser() const { return Parser; } 45a2edbabcb86f213eca6daeda5d801f8c7b1e44b2Daniel Dunbar 4616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar MCAsmLexer &getLexer() const { return Parser.getLexer(); } 4716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 4816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); } 4916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 50309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner X86Operand *ParseOperand(); 51eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner X86Operand *ParseMemOperand(unsigned SegReg, SMLoc StartLoc); 529c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby 539c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby bool ParseDirectiveWord(unsigned Size, SMLoc L); 549c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby 557036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner bool MatchAndEmitInstruction(SMLoc IDLoc, 567c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands, 577036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner MCStreamer &Out); 5820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 5996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger /// isSrcOp - Returns true if operand is either (%rsi) or %ds:%(rsi) 6096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger /// in 64bit mode or (%edi) or %es:(%edi) in 32bit mode. 6196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger bool isSrcOp(X86Operand &Op); 6296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger 6396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger /// isDstOp - Returns true if operand is either %es:(%rdi) in 64bit mode 6496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger /// or %es:(%edi) in 32bit mode. 6596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger bool isDstOp(X86Operand &Op); 6696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger 6759ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng bool is64BitMode() const { 68ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng // FIXME: Can tablegen auto-generate this? 69ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng return (STI.getFeatureBits() & X86::Mode64Bit) != 0; 70ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 71ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 7254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar /// @name Auto-generated Matcher Functions 7354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar /// { 74c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer 750692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER 760692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "X86GenAsmMatcher.inc" 77c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer 780e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar /// } 7916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 8016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbarpublic: 81ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng X86ATTAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser) 82ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng : TargetAsmParser(), STI(sti), Parser(parser) { 83c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer 8454074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar // Initialize the set of available features. 85ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 8654074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar } 87bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); 8816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 8938e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc, 909898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands); 919c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby 929c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby virtual bool ParseDirective(AsmToken DirectiveID); 9316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar}; 9437dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner} // end anonymous namespace 9537dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner 96e9b466d4f09de3b46c0d0d1e71cabddc7cc9021bSean Callanan/// @name Auto-generated Match Functions 97f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes/// { 98e9b466d4f09de3b46c0d0d1e71cabddc7cc9021bSean Callanan 99b8d6e98e566724f58344d275a4bd675249bb713aChris Lattnerstatic unsigned MatchRegisterName(StringRef Name); 100e9b466d4f09de3b46c0d0d1e71cabddc7cc9021bSean Callanan 101e9b466d4f09de3b46c0d0d1e71cabddc7cc9021bSean Callanan/// } 10237dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner 10337dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattnernamespace { 10416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 10516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar/// X86Operand - Instances of this class represent a parsed X86 machine 10616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar/// instruction. 10745220a84394758c86cc29ee0e3fe6738946fbcd0Chris Lattnerstruct X86Operand : public MCParsedAsmOperand { 1081f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner enum KindTy { 10920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Token, 11016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Register, 11116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Immediate, 11216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Memory 11316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } Kind; 11416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 11529ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner SMLoc StartLoc, EndLoc; 116f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 11716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar union { 11816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar struct { 11920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar const char *Data; 12020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar unsigned Length; 12120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } Tok; 12220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 12320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar struct { 12416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar unsigned RegNo; 12516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } Reg; 12616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 12716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar struct { 1288c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar const MCExpr *Val; 12916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } Imm; 13016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 13116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar struct { 13216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar unsigned SegReg; 1338c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar const MCExpr *Disp; 13416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar unsigned BaseReg; 13516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar unsigned IndexReg; 13616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar unsigned Scale; 13716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } Mem; 138dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar }; 13916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 1400a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner X86Operand(KindTy K, SMLoc Start, SMLoc End) 1411f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner : Kind(K), StartLoc(Start), EndLoc(End) {} 142c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar 1431f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner /// getStartLoc - Get the location of the first token of this operand. 1441f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner SMLoc getStartLoc() const { return StartLoc; } 1451f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner /// getEndLoc - Get the location of the last token of this operand. 1461f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner SMLoc getEndLoc() const { return EndLoc; } 1471f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner 148b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbach virtual void print(raw_ostream &OS) const {} 149b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar 15020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar StringRef getToken() const { 15120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar assert(Kind == Token && "Invalid access!"); 15220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar return StringRef(Tok.Data, Tok.Length); 15320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 154c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar void setTokenValue(StringRef Value) { 155c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar assert(Kind == Token && "Invalid access!"); 156c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar Tok.Data = Value.data(); 157c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar Tok.Length = Value.size(); 158c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar } 15920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 16016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar unsigned getReg() const { 16116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar assert(Kind == Register && "Invalid access!"); 16216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return Reg.RegNo; 16316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 16416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 1658c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar const MCExpr *getImm() const { 166022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar assert(Kind == Immediate && "Invalid access!"); 167022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar return Imm.Val; 168022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar } 169022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar 1708c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar const MCExpr *getMemDisp() const { 171022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar assert(Kind == Memory && "Invalid access!"); 172022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar return Mem.Disp; 173022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar } 174022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar unsigned getMemSegReg() const { 175022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar assert(Kind == Memory && "Invalid access!"); 176022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar return Mem.SegReg; 177022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar } 178022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar unsigned getMemBaseReg() const { 179022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar assert(Kind == Memory && "Invalid access!"); 180022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar return Mem.BaseReg; 181022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar } 182022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar unsigned getMemIndexReg() const { 183022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar assert(Kind == Memory && "Invalid access!"); 184022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar return Mem.IndexReg; 185022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar } 186022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar unsigned getMemScale() const { 187022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar assert(Kind == Memory && "Invalid access!"); 188022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar return Mem.Scale; 189022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar } 190022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar 191a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar bool isToken() const {return Kind == Token; } 19220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 19320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar bool isImm() const { return Kind == Immediate; } 194f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 19562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar bool isImmSExti16i8() const { 1965fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar if (!isImm()) 1975fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar return false; 1985fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar 19962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // If this isn't a constant expr, just assume it fits and let relaxation 20062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // handle it. 20162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 20262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar if (!CE) 20362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar return true; 20462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar 20562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // Otherwise, check the value is in a range that makes sense for this 20662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // extension. 20762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar uint64_t Value = CE->getValue(); 20862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar return (( Value <= 0x000000000000007FULL)|| 20962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar (0x000000000000FF80ULL <= Value && Value <= 0x000000000000FFFFULL)|| 21062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL)); 21162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar } 21262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar bool isImmSExti32i8() const { 21362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar if (!isImm()) 21462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar return false; 2155fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar 21662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // If this isn't a constant expr, just assume it fits and let relaxation 21762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // handle it. 21862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 21962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar if (!CE) 22062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar return true; 22162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar 22262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // Otherwise, check the value is in a range that makes sense for this 22362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // extension. 22462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar uint64_t Value = CE->getValue(); 22562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar return (( Value <= 0x000000000000007FULL)|| 22662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar (0x00000000FFFFFF80ULL <= Value && Value <= 0x00000000FFFFFFFFULL)|| 22762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL)); 2285fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar } 22962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar bool isImmSExti64i8() const { 2301fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar if (!isImm()) 2311fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar return false; 2321fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar 23362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // If this isn't a constant expr, just assume it fits and let relaxation 23462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // handle it. 23562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 23662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar if (!CE) 23762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar return true; 23862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar 23962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // Otherwise, check the value is in a range that makes sense for this 24062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // extension. 24162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar uint64_t Value = CE->getValue(); 24262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar return (( Value <= 0x000000000000007FULL)|| 24362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL)); 24462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar } 24562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar bool isImmSExti64i32() const { 24662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar if (!isImm()) 24762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar return false; 2481fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar 24962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // If this isn't a constant expr, just assume it fits and let relaxation 25062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // handle it. 25162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 25262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar if (!CE) 25362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar return true; 25462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar 25562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // Otherwise, check the value is in a range that makes sense for this 25662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // extension. 25762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar uint64_t Value = CE->getValue(); 25862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar return (( Value <= 0x000000007FFFFFFFULL)|| 25962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar (0xFFFFFFFF80000000ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL)); 2601fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar } 2611fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar 26220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar bool isMem() const { return Kind == Memory; } 26320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 264b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar bool isAbsMem() const { 265b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar return Kind == Memory && !getMemSegReg() && !getMemBaseReg() && 2667b9147afa7d1875353e1c1347b6b6cf71f548229Daniel Dunbar !getMemIndexReg() && getMemScale() == 1; 267b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar } 268b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar 26920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar bool isReg() const { return Kind == Register; } 27020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 2719c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar void addExpr(MCInst &Inst, const MCExpr *Expr) const { 2729c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar // Add as immediates when possible. 2739c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 2749c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 2759c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar else 2769c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar Inst.addOperand(MCOperand::CreateExpr(Expr)); 2779c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar } 2789c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar 2795c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar void addRegOperands(MCInst &Inst, unsigned N) const { 28020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar assert(N == 1 && "Invalid number of operands!"); 28120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Inst.addOperand(MCOperand::CreateReg(getReg())); 28220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 28320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 2845c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar void addImmOperands(MCInst &Inst, unsigned N) const { 28520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar assert(N == 1 && "Invalid number of operands!"); 2869c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar addExpr(Inst, getImm()); 28720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 28820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 2895c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar void addMemOperands(MCInst &Inst, unsigned N) const { 290ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar assert((N == 5) && "Invalid number of operands!"); 29120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Inst.addOperand(MCOperand::CreateReg(getMemBaseReg())); 29220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Inst.addOperand(MCOperand::CreateImm(getMemScale())); 29320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Inst.addOperand(MCOperand::CreateReg(getMemIndexReg())); 2949c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar addExpr(Inst, getMemDisp()); 295ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar Inst.addOperand(MCOperand::CreateReg(getMemSegReg())); 296ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar } 297ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar 298b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar void addAbsMemOperands(MCInst &Inst, unsigned N) const { 299b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar assert((N == 1) && "Invalid number of operands!"); 300b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar Inst.addOperand(MCOperand::CreateExpr(getMemDisp())); 301b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar } 302b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar 303b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner static X86Operand *CreateToken(StringRef Str, SMLoc Loc) { 304b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner X86Operand *Res = new X86Operand(Token, Loc, Loc); 30529ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner Res->Tok.Data = Str.data(); 30629ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner Res->Tok.Length = Str.size(); 30720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar return Res; 30820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 30920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 31029ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner static X86Operand *CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc) { 3111f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner X86Operand *Res = new X86Operand(Register, StartLoc, EndLoc); 31229ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner Res->Reg.RegNo = RegNo; 31329ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner return Res; 31416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 31520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 316b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner static X86Operand *CreateImm(const MCExpr *Val, SMLoc StartLoc, SMLoc EndLoc){ 317b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner X86Operand *Res = new X86Operand(Immediate, StartLoc, EndLoc); 31829ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner Res->Imm.Val = Val; 31929ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner return Res; 32016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 32120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 322b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar /// Create an absolute memory operand. 323b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar static X86Operand *CreateMem(const MCExpr *Disp, SMLoc StartLoc, 324b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar SMLoc EndLoc) { 325b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc); 326b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar Res->Mem.SegReg = 0; 327b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar Res->Mem.Disp = Disp; 328b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar Res->Mem.BaseReg = 0; 329b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar Res->Mem.IndexReg = 0; 3307b9147afa7d1875353e1c1347b6b6cf71f548229Daniel Dunbar Res->Mem.Scale = 1; 331b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar return Res; 332b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar } 333b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar 334b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar /// Create a generalized memory operand. 335309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner static X86Operand *CreateMem(unsigned SegReg, const MCExpr *Disp, 336309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner unsigned BaseReg, unsigned IndexReg, 3370a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner unsigned Scale, SMLoc StartLoc, SMLoc EndLoc) { 338b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar // We should never just have a displacement, that should be parsed as an 339b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar // absolute memory operand. 340c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!"); 341c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar 342022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar // The scale should always be one of {1,2,4,8}. 343022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) && 34416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar "Invalid scale!"); 3450a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc); 34629ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner Res->Mem.SegReg = SegReg; 34729ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner Res->Mem.Disp = Disp; 34829ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner Res->Mem.BaseReg = BaseReg; 34929ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner Res->Mem.IndexReg = IndexReg; 35029ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner Res->Mem.Scale = Scale; 35129ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner return Res; 35216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 35316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar}; 35416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 35537dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner} // end anonymous namespace. 35616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 35796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenbergerbool X86ATTAsmParser::isSrcOp(X86Operand &Op) { 35859ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng unsigned basereg = is64BitMode() ? X86::RSI : X86::ESI; 35996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger 36096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger return (Op.isMem() && 36196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger (Op.Mem.SegReg == 0 || Op.Mem.SegReg == X86::DS) && 36296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger isa<MCConstantExpr>(Op.Mem.Disp) && 36396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 && 36496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger Op.Mem.BaseReg == basereg && Op.Mem.IndexReg == 0); 36596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger} 36696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger 36796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenbergerbool X86ATTAsmParser::isDstOp(X86Operand &Op) { 36859ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng unsigned basereg = is64BitMode() ? X86::RDI : X86::EDI; 36996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger 37096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger return Op.isMem() && Op.Mem.SegReg == X86::ES && 37196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger isa<MCConstantExpr>(Op.Mem.Disp) && 37296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 && 37396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger Op.Mem.BaseReg == basereg && Op.Mem.IndexReg == 0; 37496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger} 37516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 37629ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattnerbool X86ATTAsmParser::ParseRegister(unsigned &RegNo, 37729ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner SMLoc &StartLoc, SMLoc &EndLoc) { 37823075746a1418f281bc2a088ea85560bfd833599Chris Lattner RegNo = 0; 37918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &TokPercent = Parser.getTok(); 3807b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby assert(TokPercent.is(AsmToken::Percent) && "Invalid token kind!"); 38129ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner StartLoc = TokPercent.getLoc(); 382b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat percent token. 3837b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby 38418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 3850d6cd00dbe58b456d0d33663e6a36c270aad2b5aKevin Enderby if (Tok.isNot(AsmToken::Identifier)) 3860d6cd00dbe58b456d0d33663e6a36c270aad2b5aKevin Enderby return Error(Tok.getLoc(), "invalid register name"); 38716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 3880e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar // FIXME: Validate register for the current architecture; we have to do 3890e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar // validation later, so maybe there is no need for this here. 3907b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby RegNo = MatchRegisterName(Tok.getString()); 391f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 39233d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner // If the match failed, try the register name as lowercase. 39333d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner if (RegNo == 0) 39433d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner RegNo = MatchRegisterName(LowercaseString(Tok.getString())); 395c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer 3963c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes // FIXME: This should be done using Requires<In32BitMode> and 3973c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes // Requires<In64BitMode> so "eiz" usage in 64-bit instructions 3983c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes // can be also checked. 39959ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng if (RegNo == X86::RIZ && !is64BitMode()) 4003c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes return Error(Tok.getLoc(), "riz register in 64-bit mode only"); 4013c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes 40233d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner // Parse "%st" as "%st(0)" and "%st(1)", which is multiple tokens. 40333d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner if (RegNo == 0 && (Tok.getString() == "st" || Tok.getString() == "ST")) { 404e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner RegNo = X86::ST0; 405e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner EndLoc = Tok.getLoc(); 406e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner Parser.Lex(); // Eat 'st' 407f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 408e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner // Check to see if we have '(4)' after %st. 409e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner if (getLexer().isNot(AsmToken::LParen)) 410e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner return false; 411e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner // Lex the paren. 412e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner getParser().Lex(); 413e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner 414e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner const AsmToken &IntTok = Parser.getTok(); 415e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner if (IntTok.isNot(AsmToken::Integer)) 416e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner return Error(IntTok.getLoc(), "expected stack index"); 417e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner switch (IntTok.getIntVal()) { 418e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner case 0: RegNo = X86::ST0; break; 419e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner case 1: RegNo = X86::ST1; break; 420e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner case 2: RegNo = X86::ST2; break; 421e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner case 3: RegNo = X86::ST3; break; 422e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner case 4: RegNo = X86::ST4; break; 423e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner case 5: RegNo = X86::ST5; break; 424e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner case 6: RegNo = X86::ST6; break; 425e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner case 7: RegNo = X86::ST7; break; 426e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner default: return Error(IntTok.getLoc(), "invalid stack index"); 427e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner } 428f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 429e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner if (getParser().Lex().isNot(AsmToken::RParen)) 430e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner return Error(Parser.getTok().getLoc(), "expected ')'"); 431f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 432e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner EndLoc = Tok.getLoc(); 433e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner Parser.Lex(); // Eat ')' 434e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner return false; 435e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner } 436f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 437645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner // If this is "db[0-7]", match it as an alias 438645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner // for dr[0-7]. 439645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner if (RegNo == 0 && Tok.getString().size() == 3 && 440645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner Tok.getString().startswith("db")) { 441645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner switch (Tok.getString()[2]) { 442645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner case '0': RegNo = X86::DR0; break; 443645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner case '1': RegNo = X86::DR1; break; 444645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner case '2': RegNo = X86::DR2; break; 445645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner case '3': RegNo = X86::DR3; break; 446645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner case '4': RegNo = X86::DR4; break; 447645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner case '5': RegNo = X86::DR5; break; 448645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner case '6': RegNo = X86::DR6; break; 449645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner case '7': RegNo = X86::DR7; break; 450645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner } 451f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 452645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner if (RegNo != 0) { 453645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner EndLoc = Tok.getLoc(); 454645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner Parser.Lex(); // Eat it. 455645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner return false; 456645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner } 457645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner } 458f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 459245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar if (RegNo == 0) 4600e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar return Error(Tok.getLoc(), "invalid register name"); 4610e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar 46229ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner EndLoc = Tok.getLoc(); 463b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat identifier token. 46416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return false; 465092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar} 466092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar 467309264d1e4c41923ff04fb6786749185cf3b9de1Chris LattnerX86Operand *X86ATTAsmParser::ParseOperand() { 46816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar switch (getLexer().getKind()) { 46916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar default: 470eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner // Parse a memory operand with no segment register. 471eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner return ParseMemOperand(0, Parser.getTok().getLoc()); 47223075746a1418f281bc2a088ea85560bfd833599Chris Lattner case AsmToken::Percent: { 473eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner // Read the register. 47423075746a1418f281bc2a088ea85560bfd833599Chris Lattner unsigned RegNo; 47529ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner SMLoc Start, End; 47629ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner if (ParseRegister(RegNo, Start, End)) return 0; 4773c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes if (RegNo == X86::EIZ || RegNo == X86::RIZ) { 4783c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes Error(Start, "eiz and riz can only be used as index registers"); 4793c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes return 0; 4803c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes } 481f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 482eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner // If this is a segment register followed by a ':', then this is the start 483eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner // of a memory reference, otherwise this is a normal register reference. 484eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner if (getLexer().isNot(AsmToken::Colon)) 485eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner return X86Operand::CreateReg(RegNo, Start, End); 486f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 487f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 488eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner getParser().Lex(); // Eat the colon. 489eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner return ParseMemOperand(RegNo, Start); 49023075746a1418f281bc2a088ea85560bfd833599Chris Lattner } 49116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar case AsmToken::Dollar: { 49216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // $42 -> immediate. 49318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan SMLoc Start = Parser.getTok().getLoc(), End; 494b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 4958c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar const MCExpr *Val; 49654482b472a888c9efe003ad694ecf47b21878f0eChris Lattner if (getParser().ParseExpression(Val, End)) 497309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner return 0; 498b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner return X86Operand::CreateImm(Val, Start, End); 49916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 50016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 50116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar} 50216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 503eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner/// ParseMemOperand: segment: disp(basereg, indexreg, scale). The '%ds:' prefix 504eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner/// has already been parsed if present. 505eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris LattnerX86Operand *X86ATTAsmParser::ParseMemOperand(unsigned SegReg, SMLoc MemStart) { 506f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 50716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // We have to disambiguate a parenthesized expression "(4+5)" from the start 50816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)". The 50975f265fbbbb64ab060bf41c5a4677ce56014ce9fChris Lattner // only way to do this without lookahead is to eat the '(' and see what is 51075f265fbbbb64ab060bf41c5a4677ce56014ce9fChris Lattner // after it. 5118c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext()); 51216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().isNot(AsmToken::LParen)) { 51354482b472a888c9efe003ad694ecf47b21878f0eChris Lattner SMLoc ExprEnd; 51454482b472a888c9efe003ad694ecf47b21878f0eChris Lattner if (getParser().ParseExpression(Disp, ExprEnd)) return 0; 515f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 51616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // After parsing the base expression we could either have a parenthesized 51716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // memory address or not. If not, return now. If so, eat the (. 51816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().isNot(AsmToken::LParen)) { 519c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar // Unless we have a segment register, treat this as an immediate. 520309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner if (SegReg == 0) 521b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar return X86Operand::CreateMem(Disp, MemStart, ExprEnd); 5220a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd); 52316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 524f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 52516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Eat the '('. 526b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 52716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } else { 52816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Okay, we have a '('. We don't know if this is an expression or not, but 52916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // so we have to eat the ( to see beyond it. 53018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan SMLoc LParenLoc = Parser.getTok().getLoc(); 531b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the '('. 532f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 5337b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) { 53416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Nothing to do here, fall into the code below with the '(' part of the 53516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // memory operand consumed. 53616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } else { 537b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner SMLoc ExprEnd; 538f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 53916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // It must be an parenthesized expression, parse it now. 540b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner if (getParser().ParseParenExpression(Disp, ExprEnd)) 541309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner return 0; 542f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 54316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // After parsing the base expression we could either have a parenthesized 54416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // memory address or not. If not, return now. If so, eat the (. 54516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().isNot(AsmToken::LParen)) { 546c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar // Unless we have a segment register, treat this as an immediate. 547309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner if (SegReg == 0) 548b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar return X86Operand::CreateMem(Disp, LParenLoc, ExprEnd); 5490a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd); 55016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 551f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 55216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Eat the '('. 553b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 55416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 55516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 556f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 55716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // If we reached here, then we just ate the ( of the memory operand. Process 55816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // the rest of the memory operand. 559022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar unsigned BaseReg = 0, IndexReg = 0, Scale = 1; 560f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 56129ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner if (getLexer().is(AsmToken::Percent)) { 56229ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner SMLoc L; 56329ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner if (ParseRegister(BaseReg, L, L)) return 0; 5643c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes if (BaseReg == X86::EIZ || BaseReg == X86::RIZ) { 5653c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes Error(L, "eiz and riz can only be used as index registers"); 5663c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes return 0; 5673c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes } 56829ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner } 569f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 57016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().is(AsmToken::Comma)) { 571b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the comma. 57216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 57316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Following the comma we should have either an index register, or a scale 57416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // value. We don't support the later form, but we want to parse it 57516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // correctly. 57616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // 57716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Not that even though it would be completely consistent to support syntax 5783c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes // like "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this. 5797b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby if (getLexer().is(AsmToken::Percent)) { 58029ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner SMLoc L; 58129ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner if (ParseRegister(IndexReg, L, L)) return 0; 582f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 58316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().isNot(AsmToken::RParen)) { 58416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Parse the scale amount: 58516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // ::= ',' [scale-expression] 586309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner if (getLexer().isNot(AsmToken::Comma)) { 58718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan Error(Parser.getTok().getLoc(), 588309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner "expected comma in scale expression"); 589309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner return 0; 590309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner } 591b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the comma. 59216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 59316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().isNot(AsmToken::RParen)) { 59418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan SMLoc Loc = Parser.getTok().getLoc(); 59516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 59616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar int64_t ScaleVal; 59716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getParser().ParseAbsoluteExpression(ScaleVal)) 598309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner return 0; 599f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 60016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Validate the scale amount. 601309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8){ 602309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner Error(Loc, "scale factor in address must be 1, 2, 4 or 8"); 603309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner return 0; 604309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner } 60516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Scale = (unsigned)ScaleVal; 60616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 60716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 60816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } else if (getLexer().isNot(AsmToken::RParen)) { 609ee9102587e7f6fc95de9fc5731b341eeb9bfc3caDaniel Dunbar // A scale amount without an index is ignored. 61016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // index. 61118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan SMLoc Loc = Parser.getTok().getLoc(); 61216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 61316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar int64_t Value; 61416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getParser().ParseAbsoluteExpression(Value)) 615309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner return 0; 616f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 617ee9102587e7f6fc95de9fc5731b341eeb9bfc3caDaniel Dunbar if (Value != 1) 618ee9102587e7f6fc95de9fc5731b341eeb9bfc3caDaniel Dunbar Warning(Loc, "scale factor without index register is ignored"); 619ee9102587e7f6fc95de9fc5731b341eeb9bfc3caDaniel Dunbar Scale = 1; 62016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 62116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 622f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 62316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Ok, we've eaten the memory operand, verify we have a ')' and eat it too. 624309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner if (getLexer().isNot(AsmToken::RParen)) { 62518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan Error(Parser.getTok().getLoc(), "unexpected token in memory operand"); 626309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner return 0; 627309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner } 62818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan SMLoc MemEnd = Parser.getTok().getLoc(); 629b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the ')'. 630f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 6310a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale, 6320a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner MemStart, MemEnd); 633dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar} 634dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar 6359898671a74d3fc924347e679c45edaa685b3fe6eChris Lattnerbool X86ATTAsmParser:: 63638e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin KramerParseInstruction(StringRef Name, SMLoc NameLoc, 6379898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 638693173feefaa326fad0e386470846fb3199ba381Chris Lattner StringRef PatchedName = Name; 63939e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar 640d8f717911dcdccb1a60b3049ea22c7767970dcb7Chris Lattner // FIXME: Hack to recognize setneb as setne. 641d8f717911dcdccb1a60b3049ea22c7767970dcb7Chris Lattner if (PatchedName.startswith("set") && PatchedName.endswith("b") && 642d8f717911dcdccb1a60b3049ea22c7767970dcb7Chris Lattner PatchedName != "setb" && PatchedName != "setnb") 643d8f717911dcdccb1a60b3049ea22c7767970dcb7Chris Lattner PatchedName = PatchedName.substr(0, Name.size()-1); 644d8f717911dcdccb1a60b3049ea22c7767970dcb7Chris Lattner 64539e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}. 64639e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar const MCExpr *ExtraImmOp = 0; 647428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) && 64839e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar (PatchedName.endswith("ss") || PatchedName.endswith("sd") || 64939e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar PatchedName.endswith("ps") || PatchedName.endswith("pd"))) { 650428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes bool IsVCMP = PatchedName.startswith("vcmp"); 651428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes unsigned SSECCIdx = IsVCMP ? 4 : 3; 65239e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar unsigned SSEComparisonCode = StringSwitch<unsigned>( 653428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes PatchedName.slice(SSECCIdx, PatchedName.size() - 2)) 654cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("eq", 0) 655cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("lt", 1) 656cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("le", 2) 657cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("unord", 3) 658cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("neq", 4) 659cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("nlt", 5) 660cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("nle", 6) 661cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("ord", 7) 662cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("eq_uq", 8) 663cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("nge", 9) 664cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("ngt", 0x0A) 665cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("false", 0x0B) 666cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("neq_oq", 0x0C) 667cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("ge", 0x0D) 668cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("gt", 0x0E) 669cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("true", 0x0F) 670cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("eq_os", 0x10) 671cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("lt_oq", 0x11) 672cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("le_oq", 0x12) 673cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("unord_s", 0x13) 674cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("neq_us", 0x14) 675cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("nlt_uq", 0x15) 676cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("nle_uq", 0x16) 677cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("ord_s", 0x17) 678cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("eq_us", 0x18) 679cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("nge_uq", 0x19) 680cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("ngt_uq", 0x1A) 681cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("false_os", 0x1B) 682cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("neq_os", 0x1C) 683cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("ge_oq", 0x1D) 684cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("gt_oq", 0x1E) 685cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("true_us", 0x1F) 68639e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar .Default(~0U); 68739e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar if (SSEComparisonCode != ~0U) { 68839e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar ExtraImmOp = MCConstantExpr::Create(SSEComparisonCode, 68939e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar getParser().getContext()); 69039e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar if (PatchedName.endswith("ss")) { 691428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes PatchedName = IsVCMP ? "vcmpss" : "cmpss"; 69239e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar } else if (PatchedName.endswith("sd")) { 693428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes PatchedName = IsVCMP ? "vcmpsd" : "cmpsd"; 69439e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar } else if (PatchedName.endswith("ps")) { 695428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes PatchedName = IsVCMP ? "vcmpps" : "cmpps"; 69639e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar } else { 69739e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar assert(PatchedName.endswith("pd") && "Unexpected mnemonic!"); 698428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes PatchedName = IsVCMP ? "vcmppd" : "cmppd"; 69939e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar } 70039e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar } 70139e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar } 702f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes 7031b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc)); 70416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 70539e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar if (ExtraImmOp) 70639e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar Operands.push_back(X86Operand::CreateImm(ExtraImmOp, NameLoc, NameLoc)); 707c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer 708c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer 7092544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner // Determine whether this is an instruction prefix. 7102544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner bool isPrefix = 711693173feefaa326fad0e386470846fb3199ba381Chris Lattner Name == "lock" || Name == "rep" || 712693173feefaa326fad0e386470846fb3199ba381Chris Lattner Name == "repe" || Name == "repz" || 713beb6898df8f96ccea4ae147587479b507bb3e491Rafael Espindola Name == "repne" || Name == "repnz" || 714bfd2d26159c87262fcf462ea442f99478a2093c9Rafael Espindola Name == "rex64" || Name == "data16"; 715c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer 716c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer 7172544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner // This does the actual operand parsing. Don't parse any more if we have a 7182544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we 7192544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner // just want to parse the "lock" as the first instruction and the "incl" as 7202544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner // the next one. 7212544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner if (getLexer().isNot(AsmToken::EndOfStatement) && !isPrefix) { 7220db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar 7230db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar // Parse '*' modifier. 7240db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar if (getLexer().is(AsmToken::Star)) { 72518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan SMLoc Loc = Parser.getTok().getLoc(); 726b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner Operands.push_back(X86Operand::CreateToken("*", Loc)); 727b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the star. 7280db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar } 7290db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar 73016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Read the first operand. 731309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner if (X86Operand *Op = ParseOperand()) 732309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner Operands.push_back(Op); 733cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner else { 734cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 73516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return true; 736cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 73739e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar 73816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar while (getLexer().is(AsmToken::Comma)) { 739b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the comma. 74016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 74116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Parse and remember the operand. 742309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner if (X86Operand *Op = ParseOperand()) 743309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner Operands.push_back(Op); 744cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner else { 745cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 74616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return true; 747cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 74816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 749c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer 750cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner if (getLexer().isNot(AsmToken::EndOfStatement)) { 751c146c4d47a7ec54c14e730c30bea821c34dc4c48Chris Lattner SMLoc Loc = getLexer().getLoc(); 752cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 753c146c4d47a7ec54c14e730c30bea821c34dc4c48Chris Lattner return Error(Loc, "unexpected token in argument list"); 754cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 75516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 756c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer 7572544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner if (getLexer().is(AsmToken::EndOfStatement)) 7582544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner Parser.Lex(); // Consume the EndOfStatement 75976331754d4a06e2394c15ae8f4870f4aeaf5ca1fKevin Enderby else if (isPrefix && getLexer().is(AsmToken::Slash)) 76076331754d4a06e2394c15ae8f4870f4aeaf5ca1fKevin Enderby Parser.Lex(); // Consume the prefix separator Slash 76116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 76298c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner // This is a terrible hack to handle "out[bwl]? %al, (%dx)" -> 76398c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner // "outb %al, %dx". Out doesn't take a memory form, but this is a widely 76498c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner // documented form in various unofficial manuals, so a lot of code uses it. 76598c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner if ((Name == "outb" || Name == "outw" || Name == "outl" || Name == "out") && 76698c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner Operands.size() == 3) { 76798c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner X86Operand &Op = *(X86Operand*)Operands.back(); 76898c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner if (Op.isMem() && Op.Mem.SegReg == 0 && 76998c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner isa<MCConstantExpr>(Op.Mem.Disp) && 77098c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 && 77198c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) { 77298c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner SMLoc Loc = Op.getEndLoc(); 77398c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner Operands.back() = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc); 77498c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner delete &Op; 77598c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner } 77698c870f87b7f0c996a9ba67003d88d434d6dbcd0Chris Lattner } 77700743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger // Same hack for "in[bwl]? (%dx), %al" -> "inb %dx, %al". 77800743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger if ((Name == "inb" || Name == "inw" || Name == "inl" || Name == "in") && 77900743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger Operands.size() == 3) { 78000743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger X86Operand &Op = *(X86Operand*)Operands.begin()[1]; 78100743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger if (Op.isMem() && Op.Mem.SegReg == 0 && 78200743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger isa<MCConstantExpr>(Op.Mem.Disp) && 78300743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 && 78400743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) { 78500743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger SMLoc Loc = Op.getEndLoc(); 78600743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger Operands.begin()[1] = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc); 78700743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger delete &Op; 78800743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger } 78900743c2218ff3f0f4edce972e2d88893a19e6ef8Joerg Sonnenberger } 79096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger // Transform "ins[bwl] %dx, %es:(%edi)" into "ins[bwl]" 79196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger if (Name.startswith("ins") && Operands.size() == 3 && 79296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger (Name == "insb" || Name == "insw" || Name == "insl")) { 79396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger X86Operand &Op = *(X86Operand*)Operands.begin()[1]; 79496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger X86Operand &Op2 = *(X86Operand*)Operands.begin()[2]; 79596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger if (Op.isReg() && Op.getReg() == X86::DX && isDstOp(Op2)) { 79696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger Operands.pop_back(); 79796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger Operands.pop_back(); 79896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger delete &Op; 79996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger delete &Op2; 80096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger } 80196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger } 80296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger 80396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger // Transform "outs[bwl] %ds:(%esi), %dx" into "out[bwl]" 80496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger if (Name.startswith("outs") && Operands.size() == 3 && 80596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger (Name == "outsb" || Name == "outsw" || Name == "outsl")) { 80696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger X86Operand &Op = *(X86Operand*)Operands.begin()[1]; 80796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger X86Operand &Op2 = *(X86Operand*)Operands.begin()[2]; 80896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger if (isSrcOp(Op) && Op2.isReg() && Op2.getReg() == X86::DX) { 80996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger Operands.pop_back(); 81096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger Operands.pop_back(); 81196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger delete &Op; 81296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger delete &Op2; 81396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger } 81496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger } 81596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger 81696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger // Transform "movs[bwl] %ds:(%esi), %es:(%edi)" into "movs[bwl]" 81796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger if (Name.startswith("movs") && Operands.size() == 3 && 81896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger (Name == "movsb" || Name == "movsw" || Name == "movsl" || 81959ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng (is64BitMode() && Name == "movsq"))) { 82096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger X86Operand &Op = *(X86Operand*)Operands.begin()[1]; 82196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger X86Operand &Op2 = *(X86Operand*)Operands.begin()[2]; 82296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger if (isSrcOp(Op) && isDstOp(Op2)) { 82396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger Operands.pop_back(); 82496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger Operands.pop_back(); 82596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger delete &Op; 82696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger delete &Op2; 82796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger } 82896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger } 82996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger // Transform "lods[bwl] %ds:(%esi),{%al,%ax,%eax,%rax}" into "lods[bwl]" 83096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger if (Name.startswith("lods") && Operands.size() == 3 && 83196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger (Name == "lods" || Name == "lodsb" || Name == "lodsw" || 83259ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng Name == "lodsl" || (is64BitMode() && Name == "lodsq"))) { 83396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]); 83496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger X86Operand *Op2 = static_cast<X86Operand*>(Operands[2]); 83596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger if (isSrcOp(*Op1) && Op2->isReg()) { 83696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger const char *ins; 83796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger unsigned reg = Op2->getReg(); 83896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger bool isLods = Name == "lods"; 83996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger if (reg == X86::AL && (isLods || Name == "lodsb")) 84096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger ins = "lodsb"; 84196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger else if (reg == X86::AX && (isLods || Name == "lodsw")) 84296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger ins = "lodsw"; 84396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger else if (reg == X86::EAX && (isLods || Name == "lodsl")) 84496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger ins = "lodsl"; 84596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger else if (reg == X86::RAX && (isLods || Name == "lodsq")) 84696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger ins = "lodsq"; 84796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger else 84896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger ins = NULL; 84996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger if (ins != NULL) { 85096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger Operands.pop_back(); 85196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger Operands.pop_back(); 85296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger delete Op1; 85396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger delete Op2; 85496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger if (Name != ins) 85596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger static_cast<X86Operand*>(Operands[0])->setTokenValue(ins); 85696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger } 85796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger } 85896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger } 85996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger // Transform "stos[bwl] {%al,%ax,%eax,%rax},%es:(%edi)" into "stos[bwl]" 86096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger if (Name.startswith("stos") && Operands.size() == 3 && 86196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger (Name == "stos" || Name == "stosb" || Name == "stosw" || 86259ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng Name == "stosl" || (is64BitMode() && Name == "stosq"))) { 86396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]); 86496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger X86Operand *Op2 = static_cast<X86Operand*>(Operands[2]); 86596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger if (isDstOp(*Op2) && Op1->isReg()) { 86696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger const char *ins; 86796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger unsigned reg = Op1->getReg(); 86896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger bool isStos = Name == "stos"; 86996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger if (reg == X86::AL && (isStos || Name == "stosb")) 87096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger ins = "stosb"; 87196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger else if (reg == X86::AX && (isStos || Name == "stosw")) 87296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger ins = "stosw"; 87396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger else if (reg == X86::EAX && (isStos || Name == "stosl")) 87496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger ins = "stosl"; 87596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger else if (reg == X86::RAX && (isStos || Name == "stosq")) 87696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger ins = "stosq"; 87796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger else 87896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger ins = NULL; 87996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger if (ins != NULL) { 88096622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger Operands.pop_back(); 88196622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger Operands.pop_back(); 88296622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger delete Op1; 88396622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger delete Op2; 88496622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger if (Name != ins) 88596622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger static_cast<X86Operand*>(Operands[0])->setTokenValue(ins); 88696622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger } 88796622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger } 88896622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger } 88996622aa063435b1de085489f0e3e49b5912c22daJoerg Sonnenberger 890e9e16a36d9ff355dab60e4b95673bf7a0cd27e86Chris Lattner // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>. Canonicalize to 891ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner // "shift <op>". 892d5e7705a05947e60806b795880f09757e835f590Daniel Dunbar if ((Name.startswith("shr") || Name.startswith("sar") || 8938c24b0c6996a8f03ff32766f0695dcf19577af59Chris Lattner Name.startswith("shl") || Name.startswith("sal") || 8948c24b0c6996a8f03ff32766f0695dcf19577af59Chris Lattner Name.startswith("rcl") || Name.startswith("rcr") || 8958c24b0c6996a8f03ff32766f0695dcf19577af59Chris Lattner Name.startswith("rol") || Name.startswith("ror")) && 89647ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner Operands.size() == 3) { 89747ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]); 89847ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner if (Op1->isImm() && isa<MCConstantExpr>(Op1->getImm()) && 89947ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner cast<MCConstantExpr>(Op1->getImm())->getValue() == 1) { 90047ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner delete Operands[1]; 90147ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner Operands.erase(Operands.begin() + 1); 90247ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner } 903f2de13f8d7bed958538bbd9dbeb9b15ea48456ccDaniel Dunbar } 90415f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner 90515f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner // Transforms "int $3" into "int3" as a size optimization. We can't write an 90615f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner // instalias with an immediate operand yet. 90715f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner if (Name == "int" && Operands.size() == 2) { 90815f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]); 90915f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner if (Op1->isImm() && isa<MCConstantExpr>(Op1->getImm()) && 91015f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner cast<MCConstantExpr>(Op1->getImm())->getValue() == 3) { 91115f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner delete Operands[1]; 91215f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner Operands.erase(Operands.begin() + 1); 91315f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner static_cast<X86Operand*>(Operands[0])->setTokenValue("int3"); 91415f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner } 91515f895179953b258e4ca20860d0d58f25f3a3edbChris Lattner } 916c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer 9179898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner return false; 918a3af370dc12f6d5100da5d614ab0a62da135569aDaniel Dunbar} 919a3af370dc12f6d5100da5d614ab0a62da135569aDaniel Dunbar 9202d592d10a57887ebe7c43a5e610f4278dd6c5d20Chris Lattnerbool X86ATTAsmParser:: 9217036f8be4df8a1a830ca01afe9497b035a5647d6Chris LattnerMatchAndEmitInstruction(SMLoc IDLoc, 9227c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands, 9237036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner MCStreamer &Out) { 924f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar assert(!Operands.empty() && "Unexpect empty operand list!"); 9257c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner X86Operand *Op = static_cast<X86Operand*>(Operands[0]); 9267c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner assert(Op->isToken() && "Leading operand should always be a mnemonic!"); 9277c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner 9287c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner // First, handle aliases that expand to multiple instructions. 9297c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner // FIXME: This should be replaced with a real .td file alias mechanism. 93090fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner // Also, MatchInstructionImpl should do actually *do* the EmitInstruction 93190fd797dc739319347861d4f3984bc8952ae9a29Chris Lattner // call. 9320966ec08610c02c8556105f2fff88a7e7247a549Andrew Trick if (Op->getToken() == "fstsw" || Op->getToken() == "fstcw" || 9338b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner Op->getToken() == "fstsww" || Op->getToken() == "fstcww" || 934905f2e06691672c236ae864faf0ad7220afc2844Chris Lattner Op->getToken() == "finit" || Op->getToken() == "fsave" || 9355a378076a44ef3f507b91aa8e7715fabaec42074Kevin Enderby Op->getToken() == "fstenv" || Op->getToken() == "fclex") { 9367c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner MCInst Inst; 9377c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner Inst.setOpcode(X86::WAIT); 9387c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner Out.EmitInstruction(Inst); 939f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar 9400bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner const char *Repl = 9410bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner StringSwitch<const char*>(Op->getToken()) 9428b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner .Case("finit", "fninit") 9438b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner .Case("fsave", "fnsave") 9448b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner .Case("fstcw", "fnstcw") 9458b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner .Case("fstcww", "fnstcw") 946905f2e06691672c236ae864faf0ad7220afc2844Chris Lattner .Case("fstenv", "fnstenv") 9478b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner .Case("fstsw", "fnstsw") 9488b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner .Case("fstsww", "fnstsw") 9498b260a76445762f109cc8cf6577435c4cc59e3aaChris Lattner .Case("fclex", "fnclex") 9500bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner .Default(0); 9510bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner assert(Repl && "Unknown wait-prefixed instruction"); 952b0f96facd6e6637cb71bbeaf2f4e006f0b6348e3Benjamin Kramer delete Operands[0]; 9530bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner Operands[0] = X86Operand::CreateToken(Repl, IDLoc); 9547c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner } 955c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer 956a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner bool WasOriginallyInvalidOperand = false; 957ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner unsigned OrigErrorInfo; 9587036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner MCInst Inst; 959c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer 960c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar // First, try a direct match. 961ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner switch (MatchInstructionImpl(Operands, Inst, OrigErrorInfo)) { 962ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner case Match_Success: 9637036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner Out.EmitInstruction(Inst); 964c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar return false; 965ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner case Match_MissingFeature: 966ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 967ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner return true; 968b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar case Match_ConversionFail: 969b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar return Error(IDLoc, "unable to convert operands to instruction"); 970a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner case Match_InvalidOperand: 971a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner WasOriginallyInvalidOperand = true; 972a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner break; 973a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner case Match_MnemonicFail: 974ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner break; 975ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner } 976c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar 977c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar // FIXME: Ideally, we would only attempt suffix matches for things which are 978c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar // valid prefixes, and we could just infer the right unambiguous 979c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar // type. However, that requires substantially more matcher support than the 980c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar // following hack. 981c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer 982c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar // Change the operand to point to a temporary token. 983c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar StringRef Base = Op->getToken(); 984f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar SmallString<16> Tmp; 985f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar Tmp += Base; 986f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar Tmp += ' '; 987f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar Op->setTokenValue(Tmp.str()); 988c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar 989fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner // If this instruction starts with an 'f', then it is a floating point stack 990fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner // instruction. These come in up to three forms for 32-bit, 64-bit, and 991fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner // 80-bit floating point, which use the suffixes s,l,t respectively. 992fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner // 993fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner // Otherwise, we assume that this may be an integer instruction, which comes 994fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner // in 8/16/32/64-bit forms using the b,w,l,q suffixes respectively. 995fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0"; 996fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner 997c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar // Check for the various suffix matches. 998fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner Tmp[Base.size()] = Suffixes[0]; 999fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner unsigned ErrorInfoIgnore; 1000fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner MatchResultTy Match1, Match2, Match3, Match4; 1001fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner 1002fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner Match1 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore); 1003fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner Tmp[Base.size()] = Suffixes[1]; 1004fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner Match2 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore); 1005fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner Tmp[Base.size()] = Suffixes[2]; 1006fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner Match3 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore); 1007fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner Tmp[Base.size()] = Suffixes[3]; 1008fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner Match4 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore); 1009c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar 1010c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar // Restore the old token. 1011c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar Op->setTokenValue(Base); 1012c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar 1013c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar // If exactly one matched, then we treat that as a successful match (and the 1014c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar // instruction will already have been filled in correctly, since the failing 1015c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar // matches won't have modified it). 1016ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner unsigned NumSuccessfulMatches = 1017fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner (Match1 == Match_Success) + (Match2 == Match_Success) + 1018fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner (Match3 == Match_Success) + (Match4 == Match_Success); 10197036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner if (NumSuccessfulMatches == 1) { 10207036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner Out.EmitInstruction(Inst); 1021c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar return false; 10227036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner } 1023c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar 1024ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner // Otherwise, the match failed, try to produce a decent error message. 1025f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar 102609062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar // If we had multiple suffix matches, then identify this as an ambiguous 102709062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar // match. 1028ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner if (NumSuccessfulMatches > 1) { 102909062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar char MatchChars[4]; 103009062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar unsigned NumMatches = 0; 1031fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner if (Match1 == Match_Success) MatchChars[NumMatches++] = Suffixes[0]; 1032fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner if (Match2 == Match_Success) MatchChars[NumMatches++] = Suffixes[1]; 1033fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner if (Match3 == Match_Success) MatchChars[NumMatches++] = Suffixes[2]; 1034fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner if (Match4 == Match_Success) MatchChars[NumMatches++] = Suffixes[3]; 103509062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar 103609062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar SmallString<126> Msg; 103709062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar raw_svector_ostream OS(Msg); 103809062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar OS << "ambiguous instructions require an explicit suffix (could be "; 103909062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar for (unsigned i = 0; i != NumMatches; ++i) { 104009062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar if (i != 0) 104109062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar OS << ", "; 104209062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar if (i + 1 == NumMatches) 104309062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar OS << "or "; 104409062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar OS << "'" << Base << MatchChars[i] << "'"; 104509062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar } 104609062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar OS << ")"; 104709062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar Error(IDLoc, OS.str()); 1048ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner return true; 104909062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar } 1050c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer 1051a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner // Okay, we know that none of the variants matched successfully. 1052c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer 1053a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner // If all of the instructions reported an invalid mnemonic, then the original 1054a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner // mnemonic was invalid. 1055fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner if ((Match1 == Match_MnemonicFail) && (Match2 == Match_MnemonicFail) && 1056fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner (Match3 == Match_MnemonicFail) && (Match4 == Match_MnemonicFail)) { 1057ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner if (!WasOriginallyInvalidOperand) { 1058c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer Error(IDLoc, "invalid instruction mnemonic '" + Base + "'"); 1059ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner return true; 1060ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner } 1061ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner 1062ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner // Recover location info for the operand if we know which was the problem. 1063ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner SMLoc ErrorLoc = IDLoc; 1064ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner if (OrigErrorInfo != ~0U) { 1065f884012c93578912556de6ab89ecebab79b4ee31Chris Lattner if (OrigErrorInfo >= Operands.size()) 1066f884012c93578912556de6ab89ecebab79b4ee31Chris Lattner return Error(IDLoc, "too few operands for instruction"); 1067c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer 1068ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner ErrorLoc = ((X86Operand*)Operands[OrigErrorInfo])->getStartLoc(); 1069ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 1070ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner } 1071ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner 1072f884012c93578912556de6ab89ecebab79b4ee31Chris Lattner return Error(ErrorLoc, "invalid operand for instruction"); 1073a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner } 1074c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer 1075ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner // If one instruction matched with a missing feature, report this as a 1076ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner // missing feature. 1077fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner if ((Match1 == Match_MissingFeature) + (Match2 == Match_MissingFeature) + 1078fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner (Match3 == Match_MissingFeature) + (Match4 == Match_MissingFeature) == 1){ 1079ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 1080ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner return true; 1081ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner } 1082c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer 1083a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner // If one instruction matched with an invalid operand, report this as an 1084a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner // operand failure. 1085fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner if ((Match1 == Match_InvalidOperand) + (Match2 == Match_InvalidOperand) + 1086fb7000fcbde3b5257ac055e1e5abdee5df21842bChris Lattner (Match3 == Match_InvalidOperand) + (Match4 == Match_InvalidOperand) == 1){ 1087a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner Error(IDLoc, "invalid operand for instruction"); 1088a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner return true; 1089a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner } 1090c0c8df3cea0dde2069edd10313a958508f99ec85Michael J. Spencer 1091ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner // If all of these were an outright failure, report it in a useless way. 1092ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner // FIXME: We should give nicer diagnostics about the exact failure. 1093a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner Error(IDLoc, "unknown use of instruction mnemonic without a size suffix"); 1094c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar return true; 1095c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar} 1096c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar 1097c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar 1098537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattnerbool X86ATTAsmParser::ParseDirective(AsmToken DirectiveID) { 1099537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner StringRef IDVal = DirectiveID.getIdentifier(); 1100537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner if (IDVal == ".word") 1101537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner return ParseDirectiveWord(2, DirectiveID.getLoc()); 1102537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner return true; 1103537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner} 1104537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner 1105537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner/// ParseDirectiveWord 1106537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner/// ::= .word [ expression (, expression)* ] 1107537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattnerbool X86ATTAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { 1108537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner if (getLexer().isNot(AsmToken::EndOfStatement)) { 1109537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner for (;;) { 1110537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner const MCExpr *Value; 1111537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner if (getParser().ParseExpression(Value)) 1112537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner return true; 1113537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner 1114537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner getParser().getStreamer().EmitValue(Value, Size, 0 /*addrspace*/); 1115537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner 1116537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner if (getLexer().is(AsmToken::EndOfStatement)) 1117537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner break; 1118537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner 1119537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner // FIXME: Improve diagnostic. 1120537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner if (getLexer().isNot(AsmToken::Comma)) 1121537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner return Error(L, "unexpected token in directive"); 1122537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner Parser.Lex(); 1123537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner } 1124537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner } 1125537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner 1126537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner Parser.Lex(); 1127537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner return false; 1128537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner} 1129537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner 1130537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner 1131537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner 1132537ca844dde9e6e843ada298fe8e9bac48a2c92eChris Lattner 1133e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callananextern "C" void LLVMInitializeX86AsmLexer(); 1134e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan 1135092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar// Force static initialization. 1136092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbarextern "C" void LLVMInitializeX86AsmParser() { 1137ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng RegisterAsmParser<X86ATTAsmParser> X(TheX86_32Target); 1138ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng RegisterAsmParser<X86ATTAsmParser> Y(TheX86_64Target); 1139e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan LLVMInitializeX86AsmLexer(); 1140092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar} 11410e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar 11420692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER 11430692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION 11440e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar#include "X86GenAsmMatcher.inc" 1145