X86AsmParser.cpp revision 0bb83a84d4319030c0c9260dbfea461c40eea1b2
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" 18c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmLexer.h" 19c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmParser.h" 20c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCParsedAsmOperand.h" 2133d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner#include "llvm/ADT/SmallString.h" 2233d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner#include "llvm/ADT/SmallVector.h" 2333d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner#include "llvm/ADT/StringExtras.h" 2433d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner#include "llvm/ADT/StringSwitch.h" 2533d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner#include "llvm/ADT/Twine.h" 2616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar#include "llvm/Support/SourceMgr.h" 2709062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar#include "llvm/Support/raw_ostream.h" 28092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbarusing namespace llvm; 29092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar 30092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbarnamespace { 31c6b79ac88e52367dd2afdf03b1be81b10345c0bbBenjamin Kramerstruct X86Operand; 32092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar 3316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbarclass X86ATTAsmParser : public TargetAsmParser { 3416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar MCAsmParser &Parser; 35d73ada7d24832bc2a4c3965b8f00ffd951341acfDaniel Dunbar TargetMachine &TM; 36a2edbabcb86f213eca6daeda5d801f8c7b1e44b2Daniel Dunbar 37f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbarprotected: 38f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar unsigned Is64Bit : 1; 397036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner 4016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbarprivate: 4116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar MCAsmParser &getParser() const { return Parser; } 42a2edbabcb86f213eca6daeda5d801f8c7b1e44b2Daniel Dunbar 4316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar MCAsmLexer &getLexer() const { return Parser.getLexer(); } 4416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 4516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); } 4616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 4729ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); 4816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 49309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner X86Operand *ParseOperand(); 50eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner X86Operand *ParseMemOperand(unsigned SegReg, SMLoc StartLoc); 519c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby 529c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby bool ParseDirectiveWord(unsigned Size, SMLoc L); 539c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby 547036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner bool MatchAndEmitInstruction(SMLoc IDLoc, 557c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands, 567036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner MCStreamer &Out); 5720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 5854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar /// @name Auto-generated Matcher Functions 5954074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar /// { 600692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner 610692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER 620692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "X86GenAsmMatcher.inc" 630692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner 640e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar /// } 6516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 6616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbarpublic: 67d73ada7d24832bc2a4c3965b8f00ffd951341acfDaniel Dunbar X86ATTAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &TM) 6854074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar : TargetAsmParser(T), Parser(_Parser), TM(TM) { 697036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner 7054074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar // Initialize the set of available features. 7154074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar setAvailableFeatures(ComputeAvailableFeatures( 7254074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar &TM.getSubtarget<X86Subtarget>())); 7354074b5f04f5affc77b5c6f3e5d8062b50384831Daniel Dunbar } 7416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 7538e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc, 769898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands); 779c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby 789c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby virtual bool ParseDirective(AsmToken DirectiveID); 7916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar}; 80f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 81f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbarclass X86_32ATTAsmParser : public X86ATTAsmParser { 82f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbarpublic: 83d73ada7d24832bc2a4c3965b8f00ffd951341acfDaniel Dunbar X86_32ATTAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &TM) 84d73ada7d24832bc2a4c3965b8f00ffd951341acfDaniel Dunbar : X86ATTAsmParser(T, _Parser, TM) { 85f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar Is64Bit = false; 86f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar } 87f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar}; 88f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar 89f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbarclass X86_64ATTAsmParser : public X86ATTAsmParser { 90f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbarpublic: 91d73ada7d24832bc2a4c3965b8f00ffd951341acfDaniel Dunbar X86_64ATTAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &TM) 92d73ada7d24832bc2a4c3965b8f00ffd951341acfDaniel Dunbar : X86ATTAsmParser(T, _Parser, TM) { 93f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar Is64Bit = true; 94f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar } 95f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar}; 96f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar 9737dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner} // end anonymous namespace 9837dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner 99e9b466d4f09de3b46c0d0d1e71cabddc7cc9021bSean Callanan/// @name Auto-generated Match Functions 100f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes/// { 101e9b466d4f09de3b46c0d0d1e71cabddc7cc9021bSean Callanan 102b8d6e98e566724f58344d275a4bd675249bb713aChris Lattnerstatic unsigned MatchRegisterName(StringRef Name); 103e9b466d4f09de3b46c0d0d1e71cabddc7cc9021bSean Callanan 104e9b466d4f09de3b46c0d0d1e71cabddc7cc9021bSean Callanan/// } 10537dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner 10637dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattnernamespace { 10716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 10816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar/// X86Operand - Instances of this class represent a parsed X86 machine 10916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar/// instruction. 11045220a84394758c86cc29ee0e3fe6738946fbcd0Chris Lattnerstruct X86Operand : public MCParsedAsmOperand { 1111f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner enum KindTy { 11220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Token, 11316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Register, 11416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Immediate, 11516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Memory 11616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } Kind; 11716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 11829ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner SMLoc StartLoc, EndLoc; 119f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 12016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar union { 12116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar struct { 12220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar const char *Data; 12320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar unsigned Length; 12420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } Tok; 12520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 12620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar struct { 12716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar unsigned RegNo; 12816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } Reg; 12916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 13016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar struct { 1318c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar const MCExpr *Val; 13216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } Imm; 13316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 13416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar struct { 13516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar unsigned SegReg; 1368c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar const MCExpr *Disp; 13716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar unsigned BaseReg; 13816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar unsigned IndexReg; 13916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar unsigned Scale; 14016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } Mem; 141dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar }; 14216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 1430a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner X86Operand(KindTy K, SMLoc Start, SMLoc End) 1441f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner : Kind(K), StartLoc(Start), EndLoc(End) {} 145c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar 1461f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner /// getStartLoc - Get the location of the first token of this operand. 1471f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner SMLoc getStartLoc() const { return StartLoc; } 1481f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner /// getEndLoc - Get the location of the last token of this operand. 1491f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner SMLoc getEndLoc() const { return EndLoc; } 1501f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner 151b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar virtual void dump(raw_ostream &OS) const {} 152b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar 15320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar StringRef getToken() const { 15420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar assert(Kind == Token && "Invalid access!"); 15520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar return StringRef(Tok.Data, Tok.Length); 15620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 157c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar void setTokenValue(StringRef Value) { 158c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar assert(Kind == Token && "Invalid access!"); 159c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar Tok.Data = Value.data(); 160c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar Tok.Length = Value.size(); 161c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar } 16220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 16316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar unsigned getReg() const { 16416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar assert(Kind == Register && "Invalid access!"); 16516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return Reg.RegNo; 16616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 16716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 1688c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar const MCExpr *getImm() const { 169022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar assert(Kind == Immediate && "Invalid access!"); 170022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar return Imm.Val; 171022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar } 172022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar 1738c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar const MCExpr *getMemDisp() const { 174022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar assert(Kind == Memory && "Invalid access!"); 175022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar return Mem.Disp; 176022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar } 177022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar unsigned getMemSegReg() const { 178022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar assert(Kind == Memory && "Invalid access!"); 179022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar return Mem.SegReg; 180022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar } 181022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar unsigned getMemBaseReg() const { 182022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar assert(Kind == Memory && "Invalid access!"); 183022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar return Mem.BaseReg; 184022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar } 185022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar unsigned getMemIndexReg() const { 186022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar assert(Kind == Memory && "Invalid access!"); 187022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar return Mem.IndexReg; 188022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar } 189022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar unsigned getMemScale() const { 190022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar assert(Kind == Memory && "Invalid access!"); 191022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar return Mem.Scale; 192022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar } 193022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar 194a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar bool isToken() const {return Kind == Token; } 19520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 19620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar bool isImm() const { return Kind == Immediate; } 197f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 19862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar bool isImmSExti16i8() const { 1995fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar if (!isImm()) 2005fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar return false; 2015fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar 20262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // If this isn't a constant expr, just assume it fits and let relaxation 20362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // handle it. 20462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 20562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar if (!CE) 20662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar return true; 20762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar 20862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // Otherwise, check the value is in a range that makes sense for this 20962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // extension. 21062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar uint64_t Value = CE->getValue(); 21162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar return (( Value <= 0x000000000000007FULL)|| 21262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar (0x000000000000FF80ULL <= Value && Value <= 0x000000000000FFFFULL)|| 21362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL)); 21462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar } 21562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar bool isImmSExti32i8() const { 21662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar if (!isImm()) 21762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar return false; 2185fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar 21962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // If this isn't a constant expr, just assume it fits and let relaxation 22062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // handle it. 22162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 22262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar if (!CE) 22362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar return true; 22462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar 22562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // Otherwise, check the value is in a range that makes sense for this 22662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // extension. 22762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar uint64_t Value = CE->getValue(); 22862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar return (( Value <= 0x000000000000007FULL)|| 22962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar (0x00000000FFFFFF80ULL <= Value && Value <= 0x00000000FFFFFFFFULL)|| 23062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL)); 2315fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar } 23262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar bool isImmSExti64i8() const { 2331fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar if (!isImm()) 2341fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar return false; 2351fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar 23662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // If this isn't a constant expr, just assume it fits and let relaxation 23762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // handle it. 23862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 23962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar if (!CE) 24062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar return true; 24162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar 24262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // Otherwise, check the value is in a range that makes sense for this 24362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // extension. 24462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar uint64_t Value = CE->getValue(); 24562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar return (( Value <= 0x000000000000007FULL)|| 24662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL)); 24762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar } 24862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar bool isImmSExti64i32() const { 24962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar if (!isImm()) 25062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar return false; 2511fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar 25262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // If this isn't a constant expr, just assume it fits and let relaxation 25362e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // handle it. 25462e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 25562e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar if (!CE) 25662e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar return true; 25762e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar 25862e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // Otherwise, check the value is in a range that makes sense for this 25962e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar // extension. 26062e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar uint64_t Value = CE->getValue(); 26162e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar return (( Value <= 0x000000007FFFFFFFULL)|| 26262e4c671b6b0f13c04a20bb43c05bfe84984ef34Daniel Dunbar (0xFFFFFFFF80000000ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL)); 2631fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar } 2641fe591da3e83ae95f6e97d7cd432cfbb25e680e8Daniel Dunbar 26520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar bool isMem() const { return Kind == Memory; } 26620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 267b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar bool isAbsMem() const { 268b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar return Kind == Memory && !getMemSegReg() && !getMemBaseReg() && 2697b9147afa7d1875353e1c1347b6b6cf71f548229Daniel Dunbar !getMemIndexReg() && getMemScale() == 1; 270b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar } 271b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar 27220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar bool isReg() const { return Kind == Register; } 27320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 2749c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar void addExpr(MCInst &Inst, const MCExpr *Expr) const { 2759c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar // Add as immediates when possible. 2769c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 2779c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 2789c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar else 2799c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar Inst.addOperand(MCOperand::CreateExpr(Expr)); 2809c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar } 2819c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar 2825c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar void addRegOperands(MCInst &Inst, unsigned N) const { 28320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar assert(N == 1 && "Invalid number of operands!"); 28420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Inst.addOperand(MCOperand::CreateReg(getReg())); 28520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 28620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 2875c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar void addImmOperands(MCInst &Inst, unsigned N) const { 28820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar assert(N == 1 && "Invalid number of operands!"); 2899c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar addExpr(Inst, getImm()); 29020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 29120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 2925c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar void addMemOperands(MCInst &Inst, unsigned N) const { 293ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar assert((N == 5) && "Invalid number of operands!"); 29420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Inst.addOperand(MCOperand::CreateReg(getMemBaseReg())); 29520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Inst.addOperand(MCOperand::CreateImm(getMemScale())); 29620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Inst.addOperand(MCOperand::CreateReg(getMemIndexReg())); 2979c60f534cbdec2ba58b269c4d624ae4d301ef73aDaniel Dunbar addExpr(Inst, getMemDisp()); 298ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar Inst.addOperand(MCOperand::CreateReg(getMemSegReg())); 299ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar } 300ec2b1f1beb134872aba4faf2e7a9c7eabcf64df9Daniel Dunbar 301b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar void addAbsMemOperands(MCInst &Inst, unsigned N) const { 302b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar assert((N == 1) && "Invalid number of operands!"); 303b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar Inst.addOperand(MCOperand::CreateExpr(getMemDisp())); 304b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar } 305b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar 306b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner static X86Operand *CreateToken(StringRef Str, SMLoc Loc) { 307b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner X86Operand *Res = new X86Operand(Token, Loc, Loc); 30829ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner Res->Tok.Data = Str.data(); 30929ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner Res->Tok.Length = Str.size(); 31020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar return Res; 31120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 31220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 31329ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner static X86Operand *CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc) { 3141f19f0f31dace5d145fecbe1f0f3fea4fb9ae813Chris Lattner X86Operand *Res = new X86Operand(Register, StartLoc, EndLoc); 31529ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner Res->Reg.RegNo = RegNo; 31629ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner return Res; 31716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 31820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 319b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner static X86Operand *CreateImm(const MCExpr *Val, SMLoc StartLoc, SMLoc EndLoc){ 320b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner X86Operand *Res = new X86Operand(Immediate, StartLoc, EndLoc); 32129ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner Res->Imm.Val = Val; 32229ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner return Res; 32316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 32420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 325b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar /// Create an absolute memory operand. 326b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar static X86Operand *CreateMem(const MCExpr *Disp, SMLoc StartLoc, 327b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar SMLoc EndLoc) { 328b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc); 329b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar Res->Mem.SegReg = 0; 330b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar Res->Mem.Disp = Disp; 331b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar Res->Mem.BaseReg = 0; 332b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar Res->Mem.IndexReg = 0; 3337b9147afa7d1875353e1c1347b6b6cf71f548229Daniel Dunbar Res->Mem.Scale = 1; 334b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar return Res; 335b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar } 336b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar 337b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar /// Create a generalized memory operand. 338309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner static X86Operand *CreateMem(unsigned SegReg, const MCExpr *Disp, 339309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner unsigned BaseReg, unsigned IndexReg, 3400a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner unsigned Scale, SMLoc StartLoc, SMLoc EndLoc) { 341b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar // We should never just have a displacement, that should be parsed as an 342b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar // absolute memory operand. 343c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!"); 344c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar 345022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar // The scale should always be one of {1,2,4,8}. 346022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) && 34716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar "Invalid scale!"); 3480a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc); 34929ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner Res->Mem.SegReg = SegReg; 35029ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner Res->Mem.Disp = Disp; 35129ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner Res->Mem.BaseReg = BaseReg; 35229ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner Res->Mem.IndexReg = IndexReg; 35329ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner Res->Mem.Scale = Scale; 35429ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner return Res; 35516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 35616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar}; 35716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 35837dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner} // end anonymous namespace. 35916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 36016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 36129ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattnerbool X86ATTAsmParser::ParseRegister(unsigned &RegNo, 36229ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner SMLoc &StartLoc, SMLoc &EndLoc) { 36323075746a1418f281bc2a088ea85560bfd833599Chris Lattner RegNo = 0; 36418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &TokPercent = Parser.getTok(); 3657b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby assert(TokPercent.is(AsmToken::Percent) && "Invalid token kind!"); 36629ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner StartLoc = TokPercent.getLoc(); 367b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat percent token. 3687b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby 36918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 3700d6cd00dbe58b456d0d33663e6a36c270aad2b5aKevin Enderby if (Tok.isNot(AsmToken::Identifier)) 3710d6cd00dbe58b456d0d33663e6a36c270aad2b5aKevin Enderby return Error(Tok.getLoc(), "invalid register name"); 37216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 3730e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar // FIXME: Validate register for the current architecture; we have to do 3740e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar // validation later, so maybe there is no need for this here. 3757b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby RegNo = MatchRegisterName(Tok.getString()); 376f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 37733d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner // If the match failed, try the register name as lowercase. 37833d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner if (RegNo == 0) 37933d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner RegNo = MatchRegisterName(LowercaseString(Tok.getString())); 38033d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner 3813c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes // FIXME: This should be done using Requires<In32BitMode> and 3823c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes // Requires<In64BitMode> so "eiz" usage in 64-bit instructions 3833c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes // can be also checked. 3843c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes if (RegNo == X86::RIZ && !Is64Bit) 3853c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes return Error(Tok.getLoc(), "riz register in 64-bit mode only"); 3863c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes 38733d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner // Parse "%st" as "%st(0)" and "%st(1)", which is multiple tokens. 38833d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner if (RegNo == 0 && (Tok.getString() == "st" || Tok.getString() == "ST")) { 389e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner RegNo = X86::ST0; 390e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner EndLoc = Tok.getLoc(); 391e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner Parser.Lex(); // Eat 'st' 392f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 393e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner // Check to see if we have '(4)' after %st. 394e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner if (getLexer().isNot(AsmToken::LParen)) 395e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner return false; 396e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner // Lex the paren. 397e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner getParser().Lex(); 398e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner 399e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner const AsmToken &IntTok = Parser.getTok(); 400e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner if (IntTok.isNot(AsmToken::Integer)) 401e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner return Error(IntTok.getLoc(), "expected stack index"); 402e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner switch (IntTok.getIntVal()) { 403e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner case 0: RegNo = X86::ST0; break; 404e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner case 1: RegNo = X86::ST1; break; 405e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner case 2: RegNo = X86::ST2; break; 406e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner case 3: RegNo = X86::ST3; break; 407e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner case 4: RegNo = X86::ST4; break; 408e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner case 5: RegNo = X86::ST5; break; 409e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner case 6: RegNo = X86::ST6; break; 410e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner case 7: RegNo = X86::ST7; break; 411e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner default: return Error(IntTok.getLoc(), "invalid stack index"); 412e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner } 413f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 414e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner if (getParser().Lex().isNot(AsmToken::RParen)) 415e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner return Error(Parser.getTok().getLoc(), "expected ')'"); 416f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 417e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner EndLoc = Tok.getLoc(); 418e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner Parser.Lex(); // Eat ')' 419e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner return false; 420e16b0fc3cb607bd0b8240733e2fe829d78df3833Chris Lattner } 421f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 422645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner // If this is "db[0-7]", match it as an alias 423645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner // for dr[0-7]. 424645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner if (RegNo == 0 && Tok.getString().size() == 3 && 425645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner Tok.getString().startswith("db")) { 426645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner switch (Tok.getString()[2]) { 427645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner case '0': RegNo = X86::DR0; break; 428645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner case '1': RegNo = X86::DR1; break; 429645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner case '2': RegNo = X86::DR2; break; 430645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner case '3': RegNo = X86::DR3; break; 431645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner case '4': RegNo = X86::DR4; break; 432645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner case '5': RegNo = X86::DR5; break; 433645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner case '6': RegNo = X86::DR6; break; 434645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner case '7': RegNo = X86::DR7; break; 435645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner } 436f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 437645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner if (RegNo != 0) { 438645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner EndLoc = Tok.getLoc(); 439645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner Parser.Lex(); // Eat it. 440645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner return false; 441645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner } 442645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner } 443f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 444245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar if (RegNo == 0) 4450e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar return Error(Tok.getLoc(), "invalid register name"); 4460e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar 44729ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner EndLoc = Tok.getLoc(); 448b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat identifier token. 44916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return false; 450092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar} 451092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar 452309264d1e4c41923ff04fb6786749185cf3b9de1Chris LattnerX86Operand *X86ATTAsmParser::ParseOperand() { 45316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar switch (getLexer().getKind()) { 45416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar default: 455eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner // Parse a memory operand with no segment register. 456eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner return ParseMemOperand(0, Parser.getTok().getLoc()); 45723075746a1418f281bc2a088ea85560bfd833599Chris Lattner case AsmToken::Percent: { 458eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner // Read the register. 45923075746a1418f281bc2a088ea85560bfd833599Chris Lattner unsigned RegNo; 46029ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner SMLoc Start, End; 46129ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner if (ParseRegister(RegNo, Start, End)) return 0; 4623c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes if (RegNo == X86::EIZ || RegNo == X86::RIZ) { 4633c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes Error(Start, "eiz and riz can only be used as index registers"); 4643c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes return 0; 4653c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes } 466f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 467eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner // If this is a segment register followed by a ':', then this is the start 468eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner // of a memory reference, otherwise this is a normal register reference. 469eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner if (getLexer().isNot(AsmToken::Colon)) 470eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner return X86Operand::CreateReg(RegNo, Start, End); 471f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 472f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 473eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner getParser().Lex(); // Eat the colon. 474eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner return ParseMemOperand(RegNo, Start); 47523075746a1418f281bc2a088ea85560bfd833599Chris Lattner } 47616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar case AsmToken::Dollar: { 47716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // $42 -> immediate. 47818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan SMLoc Start = Parser.getTok().getLoc(), End; 479b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 4808c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar const MCExpr *Val; 48154482b472a888c9efe003ad694ecf47b21878f0eChris Lattner if (getParser().ParseExpression(Val, End)) 482309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner return 0; 483b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner return X86Operand::CreateImm(Val, Start, End); 48416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 48516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 48616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar} 48716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 488eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner/// ParseMemOperand: segment: disp(basereg, indexreg, scale). The '%ds:' prefix 489eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris Lattner/// has already been parsed if present. 490eef6d78be1c3a685f277be3e89ff17f67ed65f49Chris LattnerX86Operand *X86ATTAsmParser::ParseMemOperand(unsigned SegReg, SMLoc MemStart) { 491f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 49216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // We have to disambiguate a parenthesized expression "(4+5)" from the start 49316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)". The 49475f265fbbbb64ab060bf41c5a4677ce56014ce9fChris Lattner // only way to do this without lookahead is to eat the '(' and see what is 49575f265fbbbb64ab060bf41c5a4677ce56014ce9fChris Lattner // after it. 4968c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext()); 49716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().isNot(AsmToken::LParen)) { 49854482b472a888c9efe003ad694ecf47b21878f0eChris Lattner SMLoc ExprEnd; 49954482b472a888c9efe003ad694ecf47b21878f0eChris Lattner if (getParser().ParseExpression(Disp, ExprEnd)) return 0; 500f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 50116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // After parsing the base expression we could either have a parenthesized 50216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // memory address or not. If not, return now. If so, eat the (. 50316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().isNot(AsmToken::LParen)) { 504c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar // Unless we have a segment register, treat this as an immediate. 505309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner if (SegReg == 0) 506b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar return X86Operand::CreateMem(Disp, MemStart, ExprEnd); 5070a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd); 50816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 509f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 51016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Eat the '('. 511b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 51216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } else { 51316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Okay, we have a '('. We don't know if this is an expression or not, but 51416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // so we have to eat the ( to see beyond it. 51518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan SMLoc LParenLoc = Parser.getTok().getLoc(); 516b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the '('. 517f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 5187b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) { 51916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Nothing to do here, fall into the code below with the '(' part of the 52016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // memory operand consumed. 52116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } else { 522b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner SMLoc ExprEnd; 523f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 52416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // It must be an parenthesized expression, parse it now. 525b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner if (getParser().ParseParenExpression(Disp, ExprEnd)) 526309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner return 0; 527f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 52816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // After parsing the base expression we could either have a parenthesized 52916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // memory address or not. If not, return now. If so, eat the (. 53016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().isNot(AsmToken::LParen)) { 531c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar // Unless we have a segment register, treat this as an immediate. 532309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner if (SegReg == 0) 533b834f5d13d824dc4da2ce0df2aa8dffb697b8974Daniel Dunbar return X86Operand::CreateMem(Disp, LParenLoc, ExprEnd); 5340a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd); 53516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 536f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 53716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Eat the '('. 538b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 53916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 54016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 541f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 54216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // If we reached here, then we just ate the ( of the memory operand. Process 54316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // the rest of the memory operand. 544022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar unsigned BaseReg = 0, IndexReg = 0, Scale = 1; 545f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 54629ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner if (getLexer().is(AsmToken::Percent)) { 54729ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner SMLoc L; 54829ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner if (ParseRegister(BaseReg, L, L)) return 0; 5493c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes if (BaseReg == X86::EIZ || BaseReg == X86::RIZ) { 5503c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes Error(L, "eiz and riz can only be used as index registers"); 5513c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes return 0; 5523c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes } 55329ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner } 554f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 55516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().is(AsmToken::Comma)) { 556b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the comma. 55716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 55816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Following the comma we should have either an index register, or a scale 55916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // value. We don't support the later form, but we want to parse it 56016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // correctly. 56116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // 56216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Not that even though it would be completely consistent to support syntax 5633c8e1bee6399e829eda801a32158c1f52d2733adBruno Cardoso Lopes // like "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this. 5647b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby if (getLexer().is(AsmToken::Percent)) { 56529ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner SMLoc L; 56629ef9a21dd4df3e92d21f4d9edf612d8da67cfe1Chris Lattner if (ParseRegister(IndexReg, L, L)) return 0; 567f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 56816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().isNot(AsmToken::RParen)) { 56916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Parse the scale amount: 57016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // ::= ',' [scale-expression] 571309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner if (getLexer().isNot(AsmToken::Comma)) { 57218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan Error(Parser.getTok().getLoc(), 573309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner "expected comma in scale expression"); 574309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner return 0; 575309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner } 576b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the comma. 57716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 57816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().isNot(AsmToken::RParen)) { 57918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan SMLoc Loc = Parser.getTok().getLoc(); 58016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 58116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar int64_t ScaleVal; 58216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getParser().ParseAbsoluteExpression(ScaleVal)) 583309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner return 0; 584f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 58516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Validate the scale amount. 586309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8){ 587309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner Error(Loc, "scale factor in address must be 1, 2, 4 or 8"); 588309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner return 0; 589309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner } 59016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Scale = (unsigned)ScaleVal; 59116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 59216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 59316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } else if (getLexer().isNot(AsmToken::RParen)) { 594ee9102587e7f6fc95de9fc5731b341eeb9bfc3caDaniel Dunbar // A scale amount without an index is ignored. 59516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // index. 59618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan SMLoc Loc = Parser.getTok().getLoc(); 59716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 59816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar int64_t Value; 59916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getParser().ParseAbsoluteExpression(Value)) 600309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner return 0; 601f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 602ee9102587e7f6fc95de9fc5731b341eeb9bfc3caDaniel Dunbar if (Value != 1) 603ee9102587e7f6fc95de9fc5731b341eeb9bfc3caDaniel Dunbar Warning(Loc, "scale factor without index register is ignored"); 604ee9102587e7f6fc95de9fc5731b341eeb9bfc3caDaniel Dunbar Scale = 1; 60516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 60616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 607f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 60816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Ok, we've eaten the memory operand, verify we have a ')' and eat it too. 609309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner if (getLexer().isNot(AsmToken::RParen)) { 61018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan Error(Parser.getTok().getLoc(), "unexpected token in memory operand"); 611309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner return 0; 612309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner } 61318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan SMLoc MemEnd = Parser.getTok().getLoc(); 614b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the ')'. 615f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 6160a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale, 6170a3c5a54a144fd05a7feeb5c9e58da36edbe888cChris Lattner MemStart, MemEnd); 618dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar} 619dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar 6209898671a74d3fc924347e679c45edaa685b3fe6eChris Lattnerbool X86ATTAsmParser:: 62138e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin KramerParseInstruction(StringRef Name, SMLoc NameLoc, 6229898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 6231b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar // FIXME: Hack to recognize "sal..." and "rep..." for now. We need a way to 6241b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar // represent alternative syntaxes in the .td file, without requiring 6251b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar // instruction duplication. 6261b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar StringRef PatchedName = StringSwitch<StringRef>(Name) 6271b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar .Case("sal", "shl") 6281b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar .Case("salb", "shlb") 6291b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar .Case("sall", "shll") 6301b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar .Case("salq", "shlq") 6311b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar .Case("salw", "shlw") 6321b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar .Case("repe", "rep") 6331b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar .Case("repz", "rep") 6341b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar .Case("repnz", "repne") 635ba8cea450f330145cc7764e23e5d8b1aadd5e131Chris Lattner .Case("iret", "iretl") 636ba8e81cca281a92fe30c25a10d8990521128be39Chris Lattner .Case("sysret", "sysretl") 637295646274276c6814d970bed86d3b4ff76ba3ee3Chris Lattner .Case("cbw", "cbtw") 638295646274276c6814d970bed86d3b4ff76ba3ee3Chris Lattner .Case("cwd", "cwtd") 639295646274276c6814d970bed86d3b4ff76ba3ee3Chris Lattner .Case("cdq", "cltd") 640b1162fc05e09c7247be1896fd4aa4ca7e76c938cChris Lattner .Case("cwde", "cwtl") 641b1162fc05e09c7247be1896fd4aa4ca7e76c938cChris Lattner .Case("cdqe", "cltq") 642df967d613704d4e4f01ecce85c1846dfab4d9a1bChris Lattner .Case("smovb", "movsb") 643df967d613704d4e4f01ecce85c1846dfab4d9a1bChris Lattner .Case("smovw", "movsw") 644df967d613704d4e4f01ecce85c1846dfab4d9a1bChris Lattner .Case("smovl", "movsl") 645df967d613704d4e4f01ecce85c1846dfab4d9a1bChris Lattner .Case("smovq", "movsq") 646d68c474ec55a3dd43f9fa8ea4c89e5fae62909abChris Lattner .Case("push", Is64Bit ? "pushq" : "pushl") 647373c458850a963ab062046529337fe976e1f944dChris Lattner .Case("pop", Is64Bit ? "popq" : "popl") 648e5e4ff974df52aa870085904b6670c4d22ada0acDan Gohman .Case("pushf", Is64Bit ? "pushfq" : "pushfl") 649e5e4ff974df52aa870085904b6670c4d22ada0acDan Gohman .Case("popf", Is64Bit ? "popfq" : "popfl") 650dfa3c9d98260f899297c11cda2b15dc44fc4f91eChris Lattner .Case("pushfd", "pushfl") 651dfa3c9d98260f899297c11cda2b15dc44fc4f91eChris Lattner .Case("popfd", "popfl") 6529d31d79493be05ab9cbf5b7fb16b52e79712eff3Kevin Enderby .Case("retl", Is64Bit ? "retl" : "ret") 6539d31d79493be05ab9cbf5b7fb16b52e79712eff3Kevin Enderby .Case("retq", Is64Bit ? "ret" : "retq") 654697d37a43625b8862a6d6993c6c5ee614fdc0843Chris Lattner .Case("setz", "sete") .Case("setnz", "setne") 655697d37a43625b8862a6d6993c6c5ee614fdc0843Chris Lattner .Case("setc", "setb") .Case("setna", "setbe") 656697d37a43625b8862a6d6993c6c5ee614fdc0843Chris Lattner .Case("setnae", "setb").Case("setnb", "setae") 657697d37a43625b8862a6d6993c6c5ee614fdc0843Chris Lattner .Case("setnbe", "seta").Case("setnc", "setae") 658697d37a43625b8862a6d6993c6c5ee614fdc0843Chris Lattner .Case("setng", "setle").Case("setnge", "setl") 659697d37a43625b8862a6d6993c6c5ee614fdc0843Chris Lattner .Case("setnl", "setge").Case("setnle", "setg") 660697d37a43625b8862a6d6993c6c5ee614fdc0843Chris Lattner .Case("setpe", "setp") .Case("setpo", "setnp") 661697d37a43625b8862a6d6993c6c5ee614fdc0843Chris Lattner .Case("jz", "je") .Case("jnz", "jne") 662697d37a43625b8862a6d6993c6c5ee614fdc0843Chris Lattner .Case("jc", "jb") .Case("jna", "jbe") 663697d37a43625b8862a6d6993c6c5ee614fdc0843Chris Lattner .Case("jnae", "jb").Case("jnb", "jae") 664697d37a43625b8862a6d6993c6c5ee614fdc0843Chris Lattner .Case("jnbe", "ja").Case("jnc", "jae") 665697d37a43625b8862a6d6993c6c5ee614fdc0843Chris Lattner .Case("jng", "jle").Case("jnge", "jl") 666697d37a43625b8862a6d6993c6c5ee614fdc0843Chris Lattner .Case("jnl", "jge").Case("jnle", "jg") 667697d37a43625b8862a6d6993c6c5ee614fdc0843Chris Lattner .Case("jpe", "jp") .Case("jpo", "jnp") 668e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner // Condition code aliases for 16-bit, 32-bit, 64-bit and unspec operands. 669e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner .Case("cmovcw", "cmovbw") .Case("cmovcl", "cmovbl") 670e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner .Case("cmovcq", "cmovbq") .Case("cmovc", "cmovb") 6710989d29d093c281a0d8b4f1b1ea22436249c4087Chris Lattner .Case("cmovnaew","cmovbw") .Case("cmovnael","cmovbl") 6720989d29d093c281a0d8b4f1b1ea22436249c4087Chris Lattner .Case("cmovnaeq","cmovbq") .Case("cmovnae", "cmovb") 673e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner .Case("cmovnaw", "cmovbew").Case("cmovnal", "cmovbel") 674e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner .Case("cmovnaq", "cmovbeq").Case("cmovna", "cmovbe") 675e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner .Case("cmovnbw", "cmovaew").Case("cmovnbl", "cmovael") 676e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner .Case("cmovnbq", "cmovaeq").Case("cmovnb", "cmovae") 677e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner .Case("cmovnbew","cmovaw") .Case("cmovnbel","cmoval") 678e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner .Case("cmovnbeq","cmovaq") .Case("cmovnbe", "cmova") 679e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner .Case("cmovncw", "cmovaew").Case("cmovncl", "cmovael") 680e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner .Case("cmovncq", "cmovaeq").Case("cmovnc", "cmovae") 681e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner .Case("cmovngw", "cmovlew").Case("cmovngl", "cmovlel") 682e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner .Case("cmovngq", "cmovleq").Case("cmovng", "cmovle") 683e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner .Case("cmovnw", "cmovgew").Case("cmovnl", "cmovgel") 684e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner .Case("cmovnq", "cmovgeq").Case("cmovn", "cmovge") 685e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner .Case("cmovngw", "cmovlew").Case("cmovngl", "cmovlel") 686e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner .Case("cmovngq", "cmovleq").Case("cmovng", "cmovle") 687e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner .Case("cmovngew","cmovlw") .Case("cmovngel","cmovll") 688e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner .Case("cmovngeq","cmovlq") .Case("cmovnge", "cmovl") 689e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner .Case("cmovnlw", "cmovgew").Case("cmovnll", "cmovgel") 690e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner .Case("cmovnlq", "cmovgeq").Case("cmovnl", "cmovge") 691e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner .Case("cmovnlew","cmovgw") .Case("cmovnlel","cmovgl") 692e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner .Case("cmovnleq","cmovgq") .Case("cmovnle", "cmovg") 693e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner .Case("cmovnzw", "cmovnew").Case("cmovnzl", "cmovnel") 694e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner .Case("cmovnzq", "cmovneq").Case("cmovnz", "cmovne") 695e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner .Case("cmovzw", "cmovew") .Case("cmovzl", "cmovel") 696e9e0fc5eed9e177c3ee7299a34e640973102ac39Chris Lattner .Case("cmovzq", "cmoveq") .Case("cmovz", "cmove") 697c2b942acf6008ac822c21722ac7ec84264d10befChris Lattner // Floating point stack cmov aliases. 698c2b942acf6008ac822c21722ac7ec84264d10befChris Lattner .Case("fcmovz", "fcmove") 699c2b942acf6008ac822c21722ac7ec84264d10befChris Lattner .Case("fcmova", "fcmovnbe") 700c2b942acf6008ac822c21722ac7ec84264d10befChris Lattner .Case("fcmovnae", "fcmovb") 701c2b942acf6008ac822c21722ac7ec84264d10befChris Lattner .Case("fcmovna", "fcmovbe") 702c2b942acf6008ac822c21722ac7ec84264d10befChris Lattner .Case("fcmovae", "fcmovnb") 7035e394429ab0a51af87056fbdaceeae879e651963Kevin Enderby .Case("fwait", "wait") 70435aa94b229d516b9eb775ad4e13a8e2d03221cf9Chris Lattner .Case("movzx", "movzb") // FIXME: Not correct. 70535aa94b229d516b9eb775ad4e13a8e2d03221cf9Chris Lattner .Case("fildq", "fildll") 7061b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar .Default(Name); 70739e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar 70839e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}. 70939e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar const MCExpr *ExtraImmOp = 0; 710428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) && 71139e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar (PatchedName.endswith("ss") || PatchedName.endswith("sd") || 71239e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar PatchedName.endswith("ps") || PatchedName.endswith("pd"))) { 713428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes bool IsVCMP = PatchedName.startswith("vcmp"); 714428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes unsigned SSECCIdx = IsVCMP ? 4 : 3; 71539e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar unsigned SSEComparisonCode = StringSwitch<unsigned>( 716428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes PatchedName.slice(SSECCIdx, PatchedName.size() - 2)) 717cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("eq", 0) 718cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("lt", 1) 719cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("le", 2) 720cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("unord", 3) 721cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("neq", 4) 722cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("nlt", 5) 723cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("nle", 6) 724cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("ord", 7) 725cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("eq_uq", 8) 726cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("nge", 9) 727cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("ngt", 0x0A) 728cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("false", 0x0B) 729cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("neq_oq", 0x0C) 730cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("ge", 0x0D) 731cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("gt", 0x0E) 732cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("true", 0x0F) 733cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("eq_os", 0x10) 734cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("lt_oq", 0x11) 735cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("le_oq", 0x12) 736cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("unord_s", 0x13) 737cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("neq_us", 0x14) 738cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("nlt_uq", 0x15) 739cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("nle_uq", 0x16) 740cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("ord_s", 0x17) 741cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("eq_us", 0x18) 742cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("nge_uq", 0x19) 743cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("ngt_uq", 0x1A) 744cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("false_os", 0x1B) 745cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("neq_os", 0x1C) 746cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("ge_oq", 0x1D) 747cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("gt_oq", 0x1E) 748cc69e13a36b2238d8e0a2fc01463d16943c08936Bruno Cardoso Lopes .Case("true_us", 0x1F) 74939e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar .Default(~0U); 75039e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar if (SSEComparisonCode != ~0U) { 75139e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar ExtraImmOp = MCConstantExpr::Create(SSEComparisonCode, 75239e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar getParser().getContext()); 75339e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar if (PatchedName.endswith("ss")) { 754428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes PatchedName = IsVCMP ? "vcmpss" : "cmpss"; 75539e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar } else if (PatchedName.endswith("sd")) { 756428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes PatchedName = IsVCMP ? "vcmpsd" : "cmpsd"; 75739e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar } else if (PatchedName.endswith("ps")) { 758428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes PatchedName = IsVCMP ? "vcmpps" : "cmpps"; 75939e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar } else { 76039e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar assert(PatchedName.endswith("pd") && "Unexpected mnemonic!"); 761428256b8186208e89995d447c5e4c9d8e5c099faBruno Cardoso Lopes PatchedName = IsVCMP ? "vcmppd" : "cmppd"; 76239e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar } 76339e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar } 76439e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar } 765f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes 766f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes // FIXME: Hack to recognize vpclmul<src1_quadword, src2_quadword>dq 767f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes if (PatchedName.startswith("vpclmul")) { 768f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes unsigned CLMULQuadWordSelect = StringSwitch<unsigned>( 769f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes PatchedName.slice(7, PatchedName.size() - 2)) 770f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes .Case("lqlq", 0x00) // src1[63:0], src2[63:0] 771f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes .Case("hqlq", 0x01) // src1[127:64], src2[63:0] 772f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes .Case("lqhq", 0x10) // src1[63:0], src2[127:64] 773f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes .Case("hqhq", 0x11) // src1[127:64], src2[127:64] 774f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes .Default(~0U); 775f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes if (CLMULQuadWordSelect != ~0U) { 776f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes ExtraImmOp = MCConstantExpr::Create(CLMULQuadWordSelect, 777f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes getParser().getContext()); 778f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes assert(PatchedName.endswith("dq") && "Unexpected mnemonic!"); 779f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes PatchedName = "vpclmulqdq"; 780f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes } 781f528d2b438b5c8fd3e2609be981e500576f5e5afBruno Cardoso Lopes } 7829607c40601b345c21af9de97ec03e124179efd24Chris Lattner 7831b6c0605915a2f626b1d3aae6f8371924e0fffe7Daniel Dunbar Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc)); 78416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 78539e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar if (ExtraImmOp) 78639e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar Operands.push_back(X86Operand::CreateImm(ExtraImmOp, NameLoc, NameLoc)); 78747ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner 7882544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner 7892544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner // Determine whether this is an instruction prefix. 7902544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner bool isPrefix = 7912544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner PatchedName == "lock" || PatchedName == "rep" || 7922544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner PatchedName == "repne"; 7932544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner 7942544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner 7952544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner // This does the actual operand parsing. Don't parse any more if we have a 7962544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we 7972544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner // just want to parse the "lock" as the first instruction and the "incl" as 7982544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner // the next one. 7992544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner if (getLexer().isNot(AsmToken::EndOfStatement) && !isPrefix) { 8000db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar 8010db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar // Parse '*' modifier. 8020db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar if (getLexer().is(AsmToken::Star)) { 80318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan SMLoc Loc = Parser.getTok().getLoc(); 804b4307b33705ef9e660db640b2f70d6246aa51165Chris Lattner Operands.push_back(X86Operand::CreateToken("*", Loc)); 805b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the star. 8060db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar } 8070db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar 80816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Read the first operand. 809309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner if (X86Operand *Op = ParseOperand()) 810309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner Operands.push_back(Op); 811cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner else { 812cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 81316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return true; 814cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 81539e2dd7bab1925e12d4a03ae7abca0eff87274d6Daniel Dunbar 81616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar while (getLexer().is(AsmToken::Comma)) { 817b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the comma. 81816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 81916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Parse and remember the operand. 820309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner if (X86Operand *Op = ParseOperand()) 821309264d1e4c41923ff04fb6786749185cf3b9de1Chris Lattner Operands.push_back(Op); 822cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner else { 823cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 82416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return true; 825cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 82616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 8272544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner 828cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner if (getLexer().isNot(AsmToken::EndOfStatement)) { 829cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 8302544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner return TokError("unexpected token in argument list"); 831cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 83216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 83334e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner 8342544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner if (getLexer().is(AsmToken::EndOfStatement)) 8352544f426927aa6dbac8d52bd9d5e12629099da82Chris Lattner Parser.Lex(); // Consume the EndOfStatement 83616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 837e9e16a36d9ff355dab60e4b95673bf7a0cd27e86Chris Lattner // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>. Canonicalize to 838ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner // "shift <op>". 839d5e7705a05947e60806b795880f09757e835f590Daniel Dunbar if ((Name.startswith("shr") || Name.startswith("sar") || 840d5e7705a05947e60806b795880f09757e835f590Daniel Dunbar Name.startswith("shl")) && 84147ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner Operands.size() == 3) { 84247ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]); 84347ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner if (Op1->isImm() && isa<MCConstantExpr>(Op1->getImm()) && 84447ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner cast<MCConstantExpr>(Op1->getImm())->getValue() == 1) { 84547ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner delete Operands[1]; 84647ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner Operands.erase(Operands.begin() + 1); 84747ab90bfa8544bc96a02443a7c430200a880bd2bChris Lattner } 848f2de13f8d7bed958538bbd9dbeb9b15ea48456ccDaniel Dunbar } 849e9e16a36d9ff355dab60e4b95673bf7a0cd27e86Chris Lattner 850e9e16a36d9ff355dab60e4b95673bf7a0cd27e86Chris Lattner // FIXME: Hack to handle recognize "rc[lr] <op>" -> "rcl $1, <op>". 851e9e16a36d9ff355dab60e4b95673bf7a0cd27e86Chris Lattner if ((Name.startswith("rcl") || Name.startswith("rcr")) && 852e9e16a36d9ff355dab60e4b95673bf7a0cd27e86Chris Lattner Operands.size() == 2) { 853e9e16a36d9ff355dab60e4b95673bf7a0cd27e86Chris Lattner const MCExpr *One = MCConstantExpr::Create(1, getParser().getContext()); 854e9e16a36d9ff355dab60e4b95673bf7a0cd27e86Chris Lattner Operands.push_back(X86Operand::CreateImm(One, NameLoc, NameLoc)); 855e9e16a36d9ff355dab60e4b95673bf7a0cd27e86Chris Lattner std::swap(Operands[1], Operands[2]); 856e9e16a36d9ff355dab60e4b95673bf7a0cd27e86Chris Lattner } 857cfad564043021c7276ce19725f43bcde233fa549Chris Lattner 858cfad564043021c7276ce19725f43bcde233fa549Chris Lattner // FIXME: Hack to handle recognize "sh[lr]d op,op" -> "shld $1, op,op". 859cfad564043021c7276ce19725f43bcde233fa549Chris Lattner if ((Name.startswith("shld") || Name.startswith("shrd")) && 860cfad564043021c7276ce19725f43bcde233fa549Chris Lattner Operands.size() == 3) { 861cfad564043021c7276ce19725f43bcde233fa549Chris Lattner const MCExpr *One = MCConstantExpr::Create(1, getParser().getContext()); 862cfad564043021c7276ce19725f43bcde233fa549Chris Lattner Operands.insert(Operands.begin()+1, 863cfad564043021c7276ce19725f43bcde233fa549Chris Lattner X86Operand::CreateImm(One, NameLoc, NameLoc)); 864cfad564043021c7276ce19725f43bcde233fa549Chris Lattner } 865cfad564043021c7276ce19725f43bcde233fa549Chris Lattner 866d5e7705a05947e60806b795880f09757e835f590Daniel Dunbar 867ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner // FIXME: Hack to handle recognize "in[bwl] <op>". Canonicalize it to 868ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner // "inb <op>, %al". 869ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner if ((Name == "inb" || Name == "inw" || Name == "inl") && 870ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner Operands.size() == 2) { 871ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner unsigned Reg; 872ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner if (Name[2] == 'b') 873ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner Reg = MatchRegisterName("al"); 874ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner else if (Name[2] == 'w') 875ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner Reg = MatchRegisterName("ax"); 876ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner else 877ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner Reg = MatchRegisterName("eax"); 878ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner SMLoc Loc = Operands.back()->getEndLoc(); 879ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner Operands.push_back(X86Operand::CreateReg(Reg, Loc, Loc)); 880ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner } 881ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner 882ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner // FIXME: Hack to handle recognize "out[bwl] <op>". Canonicalize it to 883ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner // "outb %al, <op>". 884ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner if ((Name == "outb" || Name == "outw" || Name == "outl") && 885ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner Operands.size() == 2) { 886ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner unsigned Reg; 887ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner if (Name[3] == 'b') 888ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner Reg = MatchRegisterName("al"); 889ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner else if (Name[3] == 'w') 890ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner Reg = MatchRegisterName("ax"); 891ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner else 892ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner Reg = MatchRegisterName("eax"); 893ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner SMLoc Loc = Operands.back()->getEndLoc(); 894ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner Operands.push_back(X86Operand::CreateReg(Reg, Loc, Loc)); 895ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner std::swap(Operands[1], Operands[2]); 896ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner } 897ee211d0ed632d6329922ad4c5f7a25d3d66cf551Chris Lattner 898ef63c9a9b6f79fef91dc144db9d5f217d2b83a95Chris Lattner // FIXME: Hack to handle "out[bwl]? %al, (%dx)" -> "outb %al, %dx". 899ef63c9a9b6f79fef91dc144db9d5f217d2b83a95Chris Lattner if ((Name == "outb" || Name == "outw" || Name == "outl" || Name == "out") && 900ef63c9a9b6f79fef91dc144db9d5f217d2b83a95Chris Lattner Operands.size() == 3) { 901ef63c9a9b6f79fef91dc144db9d5f217d2b83a95Chris Lattner X86Operand &Op = *(X86Operand*)Operands.back(); 902ef63c9a9b6f79fef91dc144db9d5f217d2b83a95Chris Lattner if (Op.isMem() && Op.Mem.SegReg == 0 && 903ef63c9a9b6f79fef91dc144db9d5f217d2b83a95Chris Lattner isa<MCConstantExpr>(Op.Mem.Disp) && 904ef63c9a9b6f79fef91dc144db9d5f217d2b83a95Chris Lattner cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 && 905ef63c9a9b6f79fef91dc144db9d5f217d2b83a95Chris Lattner Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) { 906ef63c9a9b6f79fef91dc144db9d5f217d2b83a95Chris Lattner SMLoc Loc = Op.getEndLoc(); 907ef63c9a9b6f79fef91dc144db9d5f217d2b83a95Chris Lattner Operands.back() = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc); 908ef63c9a9b6f79fef91dc144db9d5f217d2b83a95Chris Lattner delete &Op; 909ef63c9a9b6f79fef91dc144db9d5f217d2b83a95Chris Lattner } 910ef63c9a9b6f79fef91dc144db9d5f217d2b83a95Chris Lattner } 911ef63c9a9b6f79fef91dc144db9d5f217d2b83a95Chris Lattner 912cf50a5390c09325a7fc41640449205eced4363f6Kevin Enderby // FIXME: Hack to handle "f{mul*,add*,sub*,div*} $op, st(0)" the same as 913cf50a5390c09325a7fc41640449205eced4363f6Kevin Enderby // "f{mul*,add*,sub*,div*} $op" 914cf50a5390c09325a7fc41640449205eced4363f6Kevin Enderby if ((Name.startswith("fmul") || Name.startswith("fadd") || 915cf50a5390c09325a7fc41640449205eced4363f6Kevin Enderby Name.startswith("fsub") || Name.startswith("fdiv")) && 916cf50a5390c09325a7fc41640449205eced4363f6Kevin Enderby Operands.size() == 3 && 917cf50a5390c09325a7fc41640449205eced4363f6Kevin Enderby static_cast<X86Operand*>(Operands[2])->isReg() && 918cf50a5390c09325a7fc41640449205eced4363f6Kevin Enderby static_cast<X86Operand*>(Operands[2])->getReg() == X86::ST0) { 919cf50a5390c09325a7fc41640449205eced4363f6Kevin Enderby delete Operands[2]; 920cf50a5390c09325a7fc41640449205eced4363f6Kevin Enderby Operands.erase(Operands.begin() + 2); 921cf50a5390c09325a7fc41640449205eced4363f6Kevin Enderby } 922cb296ec0b689ccbcb08cedc5d3e090c0471eb393Chris Lattner 923cb296ec0b689ccbcb08cedc5d3e090c0471eb393Chris Lattner // FIXME: Hack to handle "f{mulp,addp} st(0), $op" the same as 924a25f933396b8408ad89218bc60b0a93f130a3ea9Chris Lattner // "f{mulp,addp} $op", since they commute. We also allow fdivrp/fsubrp even 925a25f933396b8408ad89218bc60b0a93f130a3ea9Chris Lattner // though they don't commute, solely because gas does support this. 926a25f933396b8408ad89218bc60b0a93f130a3ea9Chris Lattner if ((Name=="fmulp" || Name=="faddp" || Name=="fsubrp" || Name=="fdivrp") && 927a25f933396b8408ad89218bc60b0a93f130a3ea9Chris Lattner Operands.size() == 3 && 9282c5291b56358bf239bdfc675ed681c2da3eb4901Chris Lattner static_cast<X86Operand*>(Operands[1])->isReg() && 9292c5291b56358bf239bdfc675ed681c2da3eb4901Chris Lattner static_cast<X86Operand*>(Operands[1])->getReg() == X86::ST0) { 9302c5291b56358bf239bdfc675ed681c2da3eb4901Chris Lattner delete Operands[1]; 9312c5291b56358bf239bdfc675ed681c2da3eb4901Chris Lattner Operands.erase(Operands.begin() + 1); 9322c5291b56358bf239bdfc675ed681c2da3eb4901Chris Lattner } 9332c5291b56358bf239bdfc675ed681c2da3eb4901Chris Lattner 934fba88d49e3fbb68bb84c295a9639fe94f9a8c6aaDaniel Dunbar // FIXME: Hack to handle "imul <imm>, B" which is an alias for "imul <imm>, B, 935fba88d49e3fbb68bb84c295a9639fe94f9a8c6aaDaniel Dunbar // B". 936ae528f65ba731e2e080822496ef36db950ffe1c1Daniel Dunbar if (Name.startswith("imul") && Operands.size() == 3 && 937fba88d49e3fbb68bb84c295a9639fe94f9a8c6aaDaniel Dunbar static_cast<X86Operand*>(Operands[1])->isImm() && 938ae528f65ba731e2e080822496ef36db950ffe1c1Daniel Dunbar static_cast<X86Operand*>(Operands.back())->isReg()) { 939ae528f65ba731e2e080822496ef36db950ffe1c1Daniel Dunbar X86Operand *Op = static_cast<X86Operand*>(Operands.back()); 940ae528f65ba731e2e080822496ef36db950ffe1c1Daniel Dunbar Operands.push_back(X86Operand::CreateReg(Op->getReg(), Op->getStartLoc(), 941ae528f65ba731e2e080822496ef36db950ffe1c1Daniel Dunbar Op->getEndLoc())); 942ae528f65ba731e2e080822496ef36db950ffe1c1Daniel Dunbar } 943c5cebeb3cb44a3fd0aaee956431159757ee47914Chris Lattner 944c5cebeb3cb44a3fd0aaee956431159757ee47914Chris Lattner // 'sldt <mem>' can be encoded with either sldtw or sldtq with the same 945c5cebeb3cb44a3fd0aaee956431159757ee47914Chris Lattner // effect (both store to a 16-bit mem). Force to sldtw to avoid ambiguity 946c5cebeb3cb44a3fd0aaee956431159757ee47914Chris Lattner // errors, since its encoding is the most compact. 947c5cebeb3cb44a3fd0aaee956431159757ee47914Chris Lattner if (Name == "sldt" && Operands.size() == 2 && 948aceeb3a4e2165e94624c3e5e2e7c93e325e951ddBenjamin Kramer static_cast<X86Operand*>(Operands[1])->isMem()) { 949aceeb3a4e2165e94624c3e5e2e7c93e325e951ddBenjamin Kramer delete Operands[0]; 950c5cebeb3cb44a3fd0aaee956431159757ee47914Chris Lattner Operands[0] = X86Operand::CreateToken("sldtw", NameLoc); 951aceeb3a4e2165e94624c3e5e2e7c93e325e951ddBenjamin Kramer } 9529607c40601b345c21af9de97ec03e124179efd24Chris Lattner 9539607c40601b345c21af9de97ec03e124179efd24Chris Lattner // The assembler accepts "xchgX <reg>, <mem>" and "xchgX <mem>, <reg>" as 9549607c40601b345c21af9de97ec03e124179efd24Chris Lattner // synonyms. Our tables only have the "<reg>, <mem>" form, so if we see the 9559607c40601b345c21af9de97ec03e124179efd24Chris Lattner // other operand order, swap them. 95690b54547d9fcc381f8ec92c32756ad4da43ed9aaChris Lattner if (Name == "xchgb" || Name == "xchgw" || Name == "xchgl" || Name == "xchgq"|| 95790b54547d9fcc381f8ec92c32756ad4da43ed9aaChris Lattner Name == "xchg") 9589607c40601b345c21af9de97ec03e124179efd24Chris Lattner if (Operands.size() == 3 && 9599607c40601b345c21af9de97ec03e124179efd24Chris Lattner static_cast<X86Operand*>(Operands[1])->isMem() && 9609607c40601b345c21af9de97ec03e124179efd24Chris Lattner static_cast<X86Operand*>(Operands[2])->isReg()) { 9619607c40601b345c21af9de97ec03e124179efd24Chris Lattner std::swap(Operands[1], Operands[2]); 9629607c40601b345c21af9de97ec03e124179efd24Chris Lattner } 963ae528f65ba731e2e080822496ef36db950ffe1c1Daniel Dunbar 964c8ae35a8e8a6a39ae05b1c876afbf404e20961ffChris Lattner // The assembler accepts "testX <reg>, <mem>" and "testX <mem>, <reg>" as 965c8ae35a8e8a6a39ae05b1c876afbf404e20961ffChris Lattner // synonyms. Our tables only have the "<mem>, <reg>" form, so if we see the 966c8ae35a8e8a6a39ae05b1c876afbf404e20961ffChris Lattner // other operand order, swap them. 96790b54547d9fcc381f8ec92c32756ad4da43ed9aaChris Lattner if (Name == "testb" || Name == "testw" || Name == "testl" || Name == "testq"|| 96890b54547d9fcc381f8ec92c32756ad4da43ed9aaChris Lattner Name == "test") 969c8ae35a8e8a6a39ae05b1c876afbf404e20961ffChris Lattner if (Operands.size() == 3 && 970c8ae35a8e8a6a39ae05b1c876afbf404e20961ffChris Lattner static_cast<X86Operand*>(Operands[1])->isReg() && 971c8ae35a8e8a6a39ae05b1c876afbf404e20961ffChris Lattner static_cast<X86Operand*>(Operands[2])->isMem()) { 972c8ae35a8e8a6a39ae05b1c876afbf404e20961ffChris Lattner std::swap(Operands[1], Operands[2]); 973c8ae35a8e8a6a39ae05b1c876afbf404e20961ffChris Lattner } 974c8ae35a8e8a6a39ae05b1c876afbf404e20961ffChris Lattner 9752d592d10a57887ebe7c43a5e610f4278dd6c5d20Chris Lattner // The assembler accepts these instructions with no operand as a synonym for 9762d592d10a57887ebe7c43a5e610f4278dd6c5d20Chris Lattner // an instruction acting on st(1). e.g. "fxch" -> "fxch %st(1)". 9772d592d10a57887ebe7c43a5e610f4278dd6c5d20Chris Lattner if ((Name == "fxch" || Name == "fucom" || Name == "fucomp" || 9782d592d10a57887ebe7c43a5e610f4278dd6c5d20Chris Lattner Name == "faddp" || Name == "fsubp" || Name == "fsubrp" || 9792d592d10a57887ebe7c43a5e610f4278dd6c5d20Chris Lattner Name == "fmulp" || Name == "fdivp" || Name == "fdivrp") && 9802d592d10a57887ebe7c43a5e610f4278dd6c5d20Chris Lattner Operands.size() == 1) { 9812d592d10a57887ebe7c43a5e610f4278dd6c5d20Chris Lattner Operands.push_back(X86Operand::CreateReg(MatchRegisterName("st(1)"), 9822d592d10a57887ebe7c43a5e610f4278dd6c5d20Chris Lattner NameLoc, NameLoc)); 9832d592d10a57887ebe7c43a5e610f4278dd6c5d20Chris Lattner } 9842d592d10a57887ebe7c43a5e610f4278dd6c5d20Chris Lattner 9858f777a205e4523b773ba3af3bad007d93da56a9aChris Lattner // The assembler accepts these instructions with two few operands as a synonym 9868f777a205e4523b773ba3af3bad007d93da56a9aChris Lattner // for taking %st(1),%st(0) or X, %st(0). 9878f777a205e4523b773ba3af3bad007d93da56a9aChris Lattner if ((Name == "fcomi" || Name == "fucomi") && Operands.size() < 3) { 9888f777a205e4523b773ba3af3bad007d93da56a9aChris Lattner if (Operands.size() == 1) 9898f777a205e4523b773ba3af3bad007d93da56a9aChris Lattner Operands.push_back(X86Operand::CreateReg(MatchRegisterName("st(1)"), 9908f777a205e4523b773ba3af3bad007d93da56a9aChris Lattner NameLoc, NameLoc)); 9918f777a205e4523b773ba3af3bad007d93da56a9aChris Lattner Operands.push_back(X86Operand::CreateReg(MatchRegisterName("st(0)"), 9928f777a205e4523b773ba3af3bad007d93da56a9aChris Lattner NameLoc, NameLoc)); 9938f777a205e4523b773ba3af3bad007d93da56a9aChris Lattner } 9942d592d10a57887ebe7c43a5e610f4278dd6c5d20Chris Lattner 99584f362d8912657bb21250a65331f797d5381e9a3Chris Lattner // The assembler accepts various amounts of brokenness for fnstsw. 99684f362d8912657bb21250a65331f797d5381e9a3Chris Lattner if (Name == "fnstsw") { 99784f362d8912657bb21250a65331f797d5381e9a3Chris Lattner if (Operands.size() == 2 && 99884f362d8912657bb21250a65331f797d5381e9a3Chris Lattner static_cast<X86Operand*>(Operands[1])->isReg()) { 99984f362d8912657bb21250a65331f797d5381e9a3Chris Lattner // "fnstsw al" and "fnstsw eax" -> "fnstw" 100084f362d8912657bb21250a65331f797d5381e9a3Chris Lattner unsigned Reg = static_cast<X86Operand*>(Operands[1])->Reg.RegNo; 100184f362d8912657bb21250a65331f797d5381e9a3Chris Lattner if (Reg == MatchRegisterName("eax") || 100284f362d8912657bb21250a65331f797d5381e9a3Chris Lattner Reg == MatchRegisterName("al")) { 100384f362d8912657bb21250a65331f797d5381e9a3Chris Lattner delete Operands[1]; 100484f362d8912657bb21250a65331f797d5381e9a3Chris Lattner Operands.pop_back(); 100584f362d8912657bb21250a65331f797d5381e9a3Chris Lattner } 100684f362d8912657bb21250a65331f797d5381e9a3Chris Lattner } 100784f362d8912657bb21250a65331f797d5381e9a3Chris Lattner 100884f362d8912657bb21250a65331f797d5381e9a3Chris Lattner // "fnstw" -> "fnstw %ax" 100984f362d8912657bb21250a65331f797d5381e9a3Chris Lattner if (Operands.size() == 1) 101084f362d8912657bb21250a65331f797d5381e9a3Chris Lattner Operands.push_back(X86Operand::CreateReg(MatchRegisterName("ax"), 101184f362d8912657bb21250a65331f797d5381e9a3Chris Lattner NameLoc, NameLoc)); 101284f362d8912657bb21250a65331f797d5381e9a3Chris Lattner } 101384f362d8912657bb21250a65331f797d5381e9a3Chris Lattner 1014cbb442640fdefae48edca2b4c60555a68352b553Chris Lattner // jmp $42,$5 -> ljmp, similarly for call. 1015cbb442640fdefae48edca2b4c60555a68352b553Chris Lattner if ((Name.startswith("call") || Name.startswith("jmp")) && 1016cbb442640fdefae48edca2b4c60555a68352b553Chris Lattner Operands.size() == 3 && 1017cbb442640fdefae48edca2b4c60555a68352b553Chris Lattner static_cast<X86Operand*>(Operands[1])->isImm() && 1018cbb442640fdefae48edca2b4c60555a68352b553Chris Lattner static_cast<X86Operand*>(Operands[2])->isImm()) { 1019cbb442640fdefae48edca2b4c60555a68352b553Chris Lattner const char *NewOpName = StringSwitch<const char *>(Name) 1020cbb442640fdefae48edca2b4c60555a68352b553Chris Lattner .Case("jmp", "ljmp") 1021cbb442640fdefae48edca2b4c60555a68352b553Chris Lattner .Case("jmpw", "ljmpw") 1022cbb442640fdefae48edca2b4c60555a68352b553Chris Lattner .Case("jmpl", "ljmpl") 1023cbb442640fdefae48edca2b4c60555a68352b553Chris Lattner .Case("jmpq", "ljmpq") 1024cbb442640fdefae48edca2b4c60555a68352b553Chris Lattner .Case("call", "lcall") 1025cbb442640fdefae48edca2b4c60555a68352b553Chris Lattner .Case("callw", "lcallw") 1026cbb442640fdefae48edca2b4c60555a68352b553Chris Lattner .Case("calll", "lcalll") 1027cbb442640fdefae48edca2b4c60555a68352b553Chris Lattner .Case("callq", "lcallq") 1028cbb442640fdefae48edca2b4c60555a68352b553Chris Lattner .Default(0); 1029cbb442640fdefae48edca2b4c60555a68352b553Chris Lattner if (NewOpName) { 1030cbb442640fdefae48edca2b4c60555a68352b553Chris Lattner delete Operands[0]; 1031cbb442640fdefae48edca2b4c60555a68352b553Chris Lattner Operands[0] = X86Operand::CreateToken(NewOpName, NameLoc); 1032d0bcc9a01590c60adb4d288691120c46a49a2288Chris Lattner Name = NewOpName; 1033cbb442640fdefae48edca2b4c60555a68352b553Chris Lattner } 1034cbb442640fdefae48edca2b4c60555a68352b553Chris Lattner } 1035cbb442640fdefae48edca2b4c60555a68352b553Chris Lattner 1036d0bcc9a01590c60adb4d288691120c46a49a2288Chris Lattner // lcall and ljmp -> lcalll and ljmpl 1037d0bcc9a01590c60adb4d288691120c46a49a2288Chris Lattner if ((Name == "lcall" || Name == "ljmp") && Operands.size() == 3) { 1038d0bcc9a01590c60adb4d288691120c46a49a2288Chris Lattner delete Operands[0]; 1039d0bcc9a01590c60adb4d288691120c46a49a2288Chris Lattner Operands[0] = X86Operand::CreateToken(Name == "lcall" ? "lcalll" : "ljmpl", 1040d0bcc9a01590c60adb4d288691120c46a49a2288Chris Lattner NameLoc); 1041d0bcc9a01590c60adb4d288691120c46a49a2288Chris Lattner } 1042d0bcc9a01590c60adb4d288691120c46a49a2288Chris Lattner 10431eb1b68e3a5241591bfa18d4beb0e0cf13a48ef2Chris Lattner // call foo is not ambiguous with callw. 10441eb1b68e3a5241591bfa18d4beb0e0cf13a48ef2Chris Lattner if (Name == "call" && Operands.size() == 2) { 10451eb1b68e3a5241591bfa18d4beb0e0cf13a48ef2Chris Lattner const char *NewName = Is64Bit ? "callq" : "calll"; 10461eb1b68e3a5241591bfa18d4beb0e0cf13a48ef2Chris Lattner delete Operands[0]; 10471eb1b68e3a5241591bfa18d4beb0e0cf13a48ef2Chris Lattner Operands[0] = X86Operand::CreateToken(NewName, NameLoc); 10481eb1b68e3a5241591bfa18d4beb0e0cf13a48ef2Chris Lattner Name = NewName; 10491eb1b68e3a5241591bfa18d4beb0e0cf13a48ef2Chris Lattner } 10501eb1b68e3a5241591bfa18d4beb0e0cf13a48ef2Chris Lattner 105161129252e44067ae112dc856c64c814344b7e7c9Chris Lattner // movsd -> movsl (when no operands are specified). 105261129252e44067ae112dc856c64c814344b7e7c9Chris Lattner if (Name == "movsd" && Operands.size() == 1) { 105361129252e44067ae112dc856c64c814344b7e7c9Chris Lattner delete Operands[0]; 105461129252e44067ae112dc856c64c814344b7e7c9Chris Lattner Operands[0] = X86Operand::CreateToken("movsl", NameLoc); 105561129252e44067ae112dc856c64c814344b7e7c9Chris Lattner } 105661129252e44067ae112dc856c64c814344b7e7c9Chris Lattner 10570c289c140ee7a68e3d06b9d8ae6060758345ad4eChris Lattner // fstp <mem> -> fstps <mem>. Without this, we'll default to fstpl due to 10580c289c140ee7a68e3d06b9d8ae6060758345ad4eChris Lattner // suffix searching. 10590c289c140ee7a68e3d06b9d8ae6060758345ad4eChris Lattner if (Name == "fstp" && Operands.size() == 2 && 10600c289c140ee7a68e3d06b9d8ae6060758345ad4eChris Lattner static_cast<X86Operand*>(Operands[1])->isMem()) { 10610c289c140ee7a68e3d06b9d8ae6060758345ad4eChris Lattner delete Operands[0]; 10620c289c140ee7a68e3d06b9d8ae6060758345ad4eChris Lattner Operands[0] = X86Operand::CreateToken("fstps", NameLoc); 10630c289c140ee7a68e3d06b9d8ae6060758345ad4eChris Lattner } 10640c289c140ee7a68e3d06b9d8ae6060758345ad4eChris Lattner 1065fd8fddd830ad8322d04161f2f6bad6269a451ab2Chris Lattner 1066fd8fddd830ad8322d04161f2f6bad6269a451ab2Chris Lattner // "clr <reg>" -> "xor <reg>, <reg>". 1067fd8fddd830ad8322d04161f2f6bad6269a451ab2Chris Lattner if ((Name == "clrb" || Name == "clrw" || Name == "clrl" || Name == "clrq" || 1068fd8fddd830ad8322d04161f2f6bad6269a451ab2Chris Lattner Name == "clr") && Operands.size() == 2 && 1069fd8fddd830ad8322d04161f2f6bad6269a451ab2Chris Lattner static_cast<X86Operand*>(Operands[1])->isReg()) { 1070fd8fddd830ad8322d04161f2f6bad6269a451ab2Chris Lattner unsigned RegNo = static_cast<X86Operand*>(Operands[1])->getReg(); 1071fd8fddd830ad8322d04161f2f6bad6269a451ab2Chris Lattner Operands.push_back(X86Operand::CreateReg(RegNo, NameLoc, NameLoc)); 1072fd8fddd830ad8322d04161f2f6bad6269a451ab2Chris Lattner delete Operands[0]; 1073fd8fddd830ad8322d04161f2f6bad6269a451ab2Chris Lattner Operands[0] = X86Operand::CreateToken("xor", NameLoc); 1074fd8fddd830ad8322d04161f2f6bad6269a451ab2Chris Lattner } 1075fd8fddd830ad8322d04161f2f6bad6269a451ab2Chris Lattner 10769898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner return false; 1077a3af370dc12f6d5100da5d614ab0a62da135569aDaniel Dunbar} 1078a3af370dc12f6d5100da5d614ab0a62da135569aDaniel Dunbar 10799c656450d65034c4cd3597fff61ef17376cff090Kevin Enderbybool X86ATTAsmParser::ParseDirective(AsmToken DirectiveID) { 10809c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby StringRef IDVal = DirectiveID.getIdentifier(); 10819c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby if (IDVal == ".word") 10829c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby return ParseDirectiveWord(2, DirectiveID.getLoc()); 10839c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby return true; 10849c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby} 10859c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby 10869c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby/// ParseDirectiveWord 10879c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby/// ::= .word [ expression (, expression)* ] 10889c656450d65034c4cd3597fff61ef17376cff090Kevin Enderbybool X86ATTAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { 10899c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) { 10909c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby for (;;) { 10919c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby const MCExpr *Value; 10929c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby if (getParser().ParseExpression(Value)) 10939c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby return true; 10949c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby 1095aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner getParser().getStreamer().EmitValue(Value, Size, 0 /*addrspace*/); 10969c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby 10979c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby if (getLexer().is(AsmToken::EndOfStatement)) 10989c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby break; 1099f64a7d49a0cdc8587f5b79bb2ac7be5fe56c1746Bruno Cardoso Lopes 11009c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby // FIXME: Improve diagnostic. 11019c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby if (getLexer().isNot(AsmToken::Comma)) 11029c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby return Error(L, "unexpected token in directive"); 1103b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 11049c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby } 11059c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby } 11069c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby 1107b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 11089c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby return false; 11099c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby} 11109c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby 1111f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar 11122d592d10a57887ebe7c43a5e610f4278dd6c5d20Chris Lattnerbool X86ATTAsmParser:: 11137036f8be4df8a1a830ca01afe9497b035a5647d6Chris LattnerMatchAndEmitInstruction(SMLoc IDLoc, 11147c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands, 11157036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner MCStreamer &Out) { 1116f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar assert(!Operands.empty() && "Unexpect empty operand list!"); 11177c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner X86Operand *Op = static_cast<X86Operand*>(Operands[0]); 11187c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner assert(Op->isToken() && "Leading operand should always be a mnemonic!"); 11197c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner 11207c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner // First, handle aliases that expand to multiple instructions. 11217c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner // FIXME: This should be replaced with a real .td file alias mechanism. 11220bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner if (Op->getToken() == "fstsw" || Op->getToken() == "fstcw") { 11237c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner MCInst Inst; 11247c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner Inst.setOpcode(X86::WAIT); 11257c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner Out.EmitInstruction(Inst); 1126f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar 11277c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner delete Operands[0]; 11280bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner const char *Repl = 11290bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner StringSwitch<const char*>(Op->getToken()) 11300bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner .Case("fstsw", "fnstsw") 11310bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner .Case("fstcw", "fnstcw") 11320bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner .Default(0); 11330bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner assert(Repl && "Unknown wait-prefixed instruction"); 11340bb83a84d4319030c0c9260dbfea461c40eea1b2Chris Lattner Operands[0] = X86Operand::CreateToken(Repl, IDLoc); 11357c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner } 11367c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner 11377c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner 1138a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner bool WasOriginallyInvalidOperand = false; 1139ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner unsigned OrigErrorInfo; 11407036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner MCInst Inst; 1141a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner 1142c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar // First, try a direct match. 1143ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner switch (MatchInstructionImpl(Operands, Inst, OrigErrorInfo)) { 1144ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner case Match_Success: 11457036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner Out.EmitInstruction(Inst); 1146c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar return false; 1147ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner case Match_MissingFeature: 1148ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 1149ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner return true; 1150a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner case Match_InvalidOperand: 1151a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner WasOriginallyInvalidOperand = true; 1152a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner break; 1153a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner case Match_MnemonicFail: 1154ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner break; 1155ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner } 1156c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar 1157c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar // FIXME: Ideally, we would only attempt suffix matches for things which are 1158c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar // valid prefixes, and we could just infer the right unambiguous 1159c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar // type. However, that requires substantially more matcher support than the 1160c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar // following hack. 11610692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner 1162c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar // Change the operand to point to a temporary token. 1163c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar StringRef Base = Op->getToken(); 1164f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar SmallString<16> Tmp; 1165f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar Tmp += Base; 1166f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar Tmp += ' '; 1167f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar Op->setTokenValue(Tmp.str()); 1168c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar 1169c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar // Check for the various suffix matches. 1170c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar Tmp[Base.size()] = 'b'; 1171ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner unsigned BErrorInfo, WErrorInfo, LErrorInfo, QErrorInfo; 1172ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner MatchResultTy MatchB = MatchInstructionImpl(Operands, Inst, BErrorInfo); 1173c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar Tmp[Base.size()] = 'w'; 1174ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner MatchResultTy MatchW = MatchInstructionImpl(Operands, Inst, WErrorInfo); 1175c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar Tmp[Base.size()] = 'l'; 1176ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner MatchResultTy MatchL = MatchInstructionImpl(Operands, Inst, LErrorInfo); 11770481449a0536311b5fefc9122ce679000540e013Daniel Dunbar Tmp[Base.size()] = 'q'; 1178ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner MatchResultTy MatchQ = MatchInstructionImpl(Operands, Inst, QErrorInfo); 1179c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar 1180c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar // Restore the old token. 1181c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar Op->setTokenValue(Base); 1182c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar 1183c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar // If exactly one matched, then we treat that as a successful match (and the 1184c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar // instruction will already have been filled in correctly, since the failing 1185c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar // matches won't have modified it). 1186ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner unsigned NumSuccessfulMatches = 1187ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner (MatchB == Match_Success) + (MatchW == Match_Success) + 1188ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner (MatchL == Match_Success) + (MatchQ == Match_Success); 11897036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner if (NumSuccessfulMatches == 1) { 11907036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner Out.EmitInstruction(Inst); 1191c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar return false; 11927036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner } 1193c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar 1194ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner // Otherwise, the match failed, try to produce a decent error message. 1195f1e29d4c21d15f9e1e3a64f3b92b1aa9908e4f63Daniel Dunbar 119609062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar // If we had multiple suffix matches, then identify this as an ambiguous 119709062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar // match. 1198ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner if (NumSuccessfulMatches > 1) { 119909062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar char MatchChars[4]; 120009062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar unsigned NumMatches = 0; 1201ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner if (MatchB == Match_Success) 120209062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar MatchChars[NumMatches++] = 'b'; 1203ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner if (MatchW == Match_Success) 120409062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar MatchChars[NumMatches++] = 'w'; 1205ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner if (MatchL == Match_Success) 120609062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar MatchChars[NumMatches++] = 'l'; 1207ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner if (MatchQ == Match_Success) 120809062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar MatchChars[NumMatches++] = 'q'; 120909062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar 121009062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar SmallString<126> Msg; 121109062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar raw_svector_ostream OS(Msg); 121209062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar OS << "ambiguous instructions require an explicit suffix (could be "; 121309062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar for (unsigned i = 0; i != NumMatches; ++i) { 121409062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar if (i != 0) 121509062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar OS << ", "; 121609062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar if (i + 1 == NumMatches) 121709062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar OS << "or "; 121809062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar OS << "'" << Base << MatchChars[i] << "'"; 121909062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar } 122009062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar OS << ")"; 122109062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar Error(IDLoc, OS.str()); 1222ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner return true; 122309062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar } 1224ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner 1225a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner // Okay, we know that none of the variants matched successfully. 1226ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner 1227a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner // If all of the instructions reported an invalid mnemonic, then the original 1228a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner // mnemonic was invalid. 1229a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner if ((MatchB == Match_MnemonicFail) && (MatchW == Match_MnemonicFail) && 1230a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner (MatchL == Match_MnemonicFail) && (MatchQ == Match_MnemonicFail)) { 1231ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner if (!WasOriginallyInvalidOperand) { 1232a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner Error(IDLoc, "invalid instruction mnemonic '" + Base + "'"); 1233ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner return true; 1234ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner } 1235ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner 1236ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner // Recover location info for the operand if we know which was the problem. 1237ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner SMLoc ErrorLoc = IDLoc; 1238ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner if (OrigErrorInfo != ~0U) { 1239f884012c93578912556de6ab89ecebab79b4ee31Chris Lattner if (OrigErrorInfo >= Operands.size()) 1240f884012c93578912556de6ab89ecebab79b4ee31Chris Lattner return Error(IDLoc, "too few operands for instruction"); 1241f884012c93578912556de6ab89ecebab79b4ee31Chris Lattner 1242ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner ErrorLoc = ((X86Operand*)Operands[OrigErrorInfo])->getStartLoc(); 1243ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 1244ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner } 1245ce4a3355d96971e7edcbff3c1975f83e1ddcb8f2Chris Lattner 1246f884012c93578912556de6ab89ecebab79b4ee31Chris Lattner return Error(ErrorLoc, "invalid operand for instruction"); 1247a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner } 1248ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner 1249ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner // If one instruction matched with a missing feature, report this as a 1250ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner // missing feature. 1251ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner if ((MatchB == Match_MissingFeature) + (MatchW == Match_MissingFeature) + 1252a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner (MatchL == Match_MissingFeature) + (MatchQ == Match_MissingFeature) == 1){ 1253ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 1254ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner return true; 1255ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner } 1256ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner 1257a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner // If one instruction matched with an invalid operand, report this as an 1258a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner // operand failure. 1259a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner if ((MatchB == Match_InvalidOperand) + (MatchW == Match_InvalidOperand) + 1260a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner (MatchL == Match_InvalidOperand) + (MatchQ == Match_InvalidOperand) == 1){ 1261a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner Error(IDLoc, "invalid operand for instruction"); 1262a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner return true; 1263a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner } 1264a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner 1265ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner // If all of these were an outright failure, report it in a useless way. 1266ec6789f4f97ca1701c163132b6e3388366463090Chris Lattner // FIXME: We should give nicer diagnostics about the exact failure. 1267a008e8ac73cb3cf2eaf006fbb1b62905c8626758Chris Lattner Error(IDLoc, "unknown use of instruction mnemonic without a size suffix"); 1268c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar return true; 1269c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar} 1270c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar 1271c918d6043b823173b106c163038b14c1e2f92765Daniel Dunbar 1272e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callananextern "C" void LLVMInitializeX86AsmLexer(); 1273e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan 1274092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar// Force static initialization. 1275092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbarextern "C" void LLVMInitializeX86AsmParser() { 1276f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar RegisterAsmParser<X86_32ATTAsmParser> X(TheX86_32Target); 1277f98bc6320b61645897606ef332cff60521c1e8f3Daniel Dunbar RegisterAsmParser<X86_64ATTAsmParser> Y(TheX86_64Target); 1278e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan LLVMInitializeX86AsmLexer(); 1279092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar} 12800e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar 12810692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER 12820692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION 12830e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar#include "X86GenAsmMatcher.inc" 1284