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