X86AsmParser.cpp revision f007e853e26845cd6866b52d646455fc69f4e0af
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 104cb1e13769856716261a4d315f8202bd918502c3Daniel Dunbar#include "X86.h" 11dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar#include "llvm/ADT/SmallVector.h" 1216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar#include "llvm/ADT/Twine.h" 13a2edbabcb86f213eca6daeda5d801f8c7b1e44b2Daniel Dunbar#include "llvm/MC/MCAsmLexer.h" 14a3af370dc12f6d5100da5d614ab0a62da135569aDaniel Dunbar#include "llvm/MC/MCAsmParser.h" 159c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby#include "llvm/MC/MCStreamer.h" 168c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar#include "llvm/MC/MCExpr.h" 17a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar#include "llvm/MC/MCInst.h" 1845220a84394758c86cc29ee0e3fe6738946fbcd0Chris Lattner#include "llvm/MC/MCParsedAsmOperand.h" 1916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar#include "llvm/Support/SourceMgr.h" 20092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar#include "llvm/Target/TargetRegistry.h" 21092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar#include "llvm/Target/TargetAsmParser.h" 22092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbarusing namespace llvm; 23092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar 24092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbarnamespace { 25c6b79ac88e52367dd2afdf03b1be81b10345c0bbBenjamin Kramerstruct X86Operand; 26092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar 2716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbarclass X86ATTAsmParser : public TargetAsmParser { 2816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar MCAsmParser &Parser; 29a2edbabcb86f213eca6daeda5d801f8c7b1e44b2Daniel Dunbar 3016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbarprivate: 3116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar MCAsmParser &getParser() const { return Parser; } 32a2edbabcb86f213eca6daeda5d801f8c7b1e44b2Daniel Dunbar 3316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar MCAsmLexer &getLexer() const { return Parser.getLexer(); } 3416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 3516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); } 3616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 3716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); } 3816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 3916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar bool ParseRegister(X86Operand &Op); 4016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 4116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar bool ParseOperand(X86Operand &Op); 4216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 4316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar bool ParseMemOperand(X86Operand &Op); 449c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby 459c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby bool ParseDirectiveWord(unsigned Size, SMLoc L); 469c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby 470e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar /// @name Auto-generated Match Functions 480e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar /// { 490e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar 5020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar bool MatchInstruction(SmallVectorImpl<X86Operand> &Operands, 5120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar MCInst &Inst); 5220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 53245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar /// MatchRegisterName - Match the given string to a register name, or 0 if 54245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar /// there is no match. 55245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar unsigned MatchRegisterName(const StringRef &Name); 560e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar 570e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar /// } 5816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 5916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbarpublic: 6016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar X86ATTAsmParser(const Target &T, MCAsmParser &_Parser) 6116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar : TargetAsmParser(T), Parser(_Parser) {} 6216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 63f007e853e26845cd6866b52d646455fc69f4e0afChris Lattner virtual bool ParseInstruction(const StringRef &Name, SMLoc NameLoc, 64f007e853e26845cd6866b52d646455fc69f4e0afChris Lattner MCInst &Inst); 659c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby 669c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby virtual bool ParseDirective(AsmToken DirectiveID); 6716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar}; 6837dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner 6937dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner} // end anonymous namespace 7037dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner 7137dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner 7237dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattnernamespace { 7316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 7416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar/// X86Operand - Instances of this class represent a parsed X86 machine 7516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar/// instruction. 7645220a84394758c86cc29ee0e3fe6738946fbcd0Chris Lattnerstruct X86Operand : public MCParsedAsmOperand { 7716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar enum { 7820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Token, 7916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Register, 8016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Immediate, 8116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Memory 8216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } Kind; 8316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 8416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar union { 8516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar struct { 8620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar const char *Data; 8720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar unsigned Length; 8820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } Tok; 8920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 9020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar struct { 9116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar unsigned RegNo; 9216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } Reg; 9316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 9416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar struct { 958c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar const MCExpr *Val; 9616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } Imm; 9716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 9816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar struct { 9916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar unsigned SegReg; 1008c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar const MCExpr *Disp; 10116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar unsigned BaseReg; 10216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar unsigned IndexReg; 10316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar unsigned Scale; 10416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } Mem; 105dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar }; 10616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 10720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar StringRef getToken() const { 10820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar assert(Kind == Token && "Invalid access!"); 10920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar return StringRef(Tok.Data, Tok.Length); 11020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 11120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 11216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar unsigned getReg() const { 11316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar assert(Kind == Register && "Invalid access!"); 11416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return Reg.RegNo; 11516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 11616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 1178c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar const MCExpr *getImm() const { 118022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar assert(Kind == Immediate && "Invalid access!"); 119022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar return Imm.Val; 120022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar } 121022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar 1228c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar const MCExpr *getMemDisp() const { 123022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar assert(Kind == Memory && "Invalid access!"); 124022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar return Mem.Disp; 125022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar } 126022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar unsigned getMemSegReg() const { 127022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar assert(Kind == Memory && "Invalid access!"); 128022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar return Mem.SegReg; 129022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar } 130022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar unsigned getMemBaseReg() const { 131022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar assert(Kind == Memory && "Invalid access!"); 132022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar return Mem.BaseReg; 133022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar } 134022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar unsigned getMemIndexReg() const { 135022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar assert(Kind == Memory && "Invalid access!"); 136022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar return Mem.IndexReg; 137022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar } 138022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar unsigned getMemScale() const { 139022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar assert(Kind == Memory && "Invalid access!"); 140022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar return Mem.Scale; 141022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar } 142022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar 143a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar bool isToken() const {return Kind == Token; } 14420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 14520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar bool isImm() const { return Kind == Immediate; } 14620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 1475fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar bool isImmSExt8() const { 1485fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar // Accept immediates which fit in 8 bits when sign extended, and 1495fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar // non-absolute immediates. 1505fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar if (!isImm()) 1515fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar return false; 1525fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar 1538c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm())) { 1548c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar int64_t Value = CE->getValue(); 1558c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar return Value == (int64_t) (int8_t) Value; 1568c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar } 1575fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar 1588c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar return true; 1595fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar } 1605fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar 16120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar bool isMem() const { return Kind == Memory; } 16220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 16320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar bool isReg() const { return Kind == Register; } 16420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 1655c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar void addRegOperands(MCInst &Inst, unsigned N) const { 16620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar assert(N == 1 && "Invalid number of operands!"); 16720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Inst.addOperand(MCOperand::CreateReg(getReg())); 16820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 16920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 1705c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar void addImmOperands(MCInst &Inst, unsigned N) const { 17120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar assert(N == 1 && "Invalid number of operands!"); 1728c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar Inst.addOperand(MCOperand::CreateExpr(getImm())); 17320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 17420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 1755c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar void addImmSExt8Operands(MCInst &Inst, unsigned N) const { 1765fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar // FIXME: Support user customization of the render method. 1775fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar assert(N == 1 && "Invalid number of operands!"); 1788c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar Inst.addOperand(MCOperand::CreateExpr(getImm())); 1795fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar } 1805fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar 1815c468e3d7006e854fd41b29d5539a7adcee53904Daniel Dunbar void addMemOperands(MCInst &Inst, unsigned N) const { 18220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar assert((N == 4 || N == 5) && "Invalid number of operands!"); 18320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 18420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Inst.addOperand(MCOperand::CreateReg(getMemBaseReg())); 18520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Inst.addOperand(MCOperand::CreateImm(getMemScale())); 18620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Inst.addOperand(MCOperand::CreateReg(getMemIndexReg())); 1878c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar Inst.addOperand(MCOperand::CreateExpr(getMemDisp())); 18820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 18920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // FIXME: What a hack. 19020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (N == 5) 19120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Inst.addOperand(MCOperand::CreateReg(getMemSegReg())); 19220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 19320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 19420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar static X86Operand CreateToken(StringRef Str) { 19520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar X86Operand Res; 19620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Res.Kind = Token; 19720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Res.Tok.Data = Str.data(); 19820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Res.Tok.Length = Str.size(); 19920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar return Res; 20020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 20120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 20216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar static X86Operand CreateReg(unsigned RegNo) { 20316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar X86Operand Res; 20416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Res.Kind = Register; 20516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Res.Reg.RegNo = RegNo; 20616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return Res; 20716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 20820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 2098c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar static X86Operand CreateImm(const MCExpr *Val) { 21016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar X86Operand Res; 21116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Res.Kind = Immediate; 21216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Res.Imm.Val = Val; 21316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return Res; 21416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 21520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 2168c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar static X86Operand CreateMem(unsigned SegReg, const MCExpr *Disp, 2178c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar unsigned BaseReg, unsigned IndexReg, 2188c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar unsigned Scale) { 219c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar // We should never just have a displacement, that would be an immediate. 220c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!"); 221c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar 222022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar // The scale should always be one of {1,2,4,8}. 223022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) && 22416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar "Invalid scale!"); 22516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar X86Operand Res; 22616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Res.Kind = Memory; 22716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Res.Mem.SegReg = SegReg; 22816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Res.Mem.Disp = Disp; 22916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Res.Mem.BaseReg = BaseReg; 23016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Res.Mem.IndexReg = IndexReg; 23116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Res.Mem.Scale = Scale; 23216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return Res; 23316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 23416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar}; 23516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 23637dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner} // end anonymous namespace. 23716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 23816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 23916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbarbool X86ATTAsmParser::ParseRegister(X86Operand &Op) { 2407b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby const AsmToken &TokPercent = getLexer().getTok(); 241875f4ae789ad15dc04771f535a7568700091d0a9Duncan Sands (void)TokPercent; // Avoid warning when assertions are disabled. 2427b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby assert(TokPercent.is(AsmToken::Percent) && "Invalid token kind!"); 2437b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby getLexer().Lex(); // Eat percent token. 2447b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby 24537dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner const AsmToken &Tok = getLexer().getTok(); 2460d6cd00dbe58b456d0d33663e6a36c270aad2b5aKevin Enderby if (Tok.isNot(AsmToken::Identifier)) 2470d6cd00dbe58b456d0d33663e6a36c270aad2b5aKevin Enderby return Error(Tok.getLoc(), "invalid register name"); 24816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 2490e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar // FIXME: Validate register for the current architecture; we have to do 2500e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar // validation later, so maybe there is no need for this here. 2510e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar unsigned RegNo; 252245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar 2537b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby RegNo = MatchRegisterName(Tok.getString()); 254245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar if (RegNo == 0) 2550e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar return Error(Tok.getLoc(), "invalid register name"); 2560e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar 2570e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar Op = X86Operand::CreateReg(RegNo); 2587b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby getLexer().Lex(); // Eat identifier token. 25916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 26016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return false; 261092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar} 262092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar 263dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbarbool X86ATTAsmParser::ParseOperand(X86Operand &Op) { 26416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar switch (getLexer().getKind()) { 26516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar default: 26616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return ParseMemOperand(Op); 2677b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby case AsmToken::Percent: 26816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // FIXME: if a segment register, this could either be just the seg reg, or 26916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // the start of a memory operand. 27016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return ParseRegister(Op); 27116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar case AsmToken::Dollar: { 27216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // $42 -> immediate. 27316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar getLexer().Lex(); 2748c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar const MCExpr *Val; 2758c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar if (getParser().ParseExpression(Val)) 27616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return true; 27716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Op = X86Operand::CreateImm(Val); 27816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return false; 27916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 28016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 28116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar} 28216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 28316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar/// ParseMemOperand: segment: disp(basereg, indexreg, scale) 28416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbarbool X86ATTAsmParser::ParseMemOperand(X86Operand &Op) { 28516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // FIXME: If SegReg ':' (e.g. %gs:), eat and remember. 28616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar unsigned SegReg = 0; 28716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 28816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // We have to disambiguate a parenthesized expression "(4+5)" from the start 28916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)". The 29016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // only way to do this without lookahead is to eat the ( and see what is after 29116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // it. 2928c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext()); 29316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().isNot(AsmToken::LParen)) { 2948c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar if (getParser().ParseExpression(Disp)) return true; 29516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 29616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // After parsing the base expression we could either have a parenthesized 29716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // memory address or not. If not, return now. If so, eat the (. 29816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().isNot(AsmToken::LParen)) { 299c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar // Unless we have a segment register, treat this as an immediate. 300c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar if (SegReg) 301c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar Op = X86Operand::CreateMem(SegReg, Disp, 0, 0, 1); 302c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar else 303c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar Op = X86Operand::CreateImm(Disp); 30416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return false; 30516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 30616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 30716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Eat the '('. 30816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar getLexer().Lex(); 30916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } else { 31016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Okay, we have a '('. We don't know if this is an expression or not, but 31116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // so we have to eat the ( to see beyond it. 31216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar getLexer().Lex(); // Eat the '('. 31316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 3147b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) { 31516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Nothing to do here, fall into the code below with the '(' part of the 31616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // memory operand consumed. 31716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } else { 31816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // It must be an parenthesized expression, parse it now. 3198c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar if (getParser().ParseParenExpression(Disp)) 32016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return true; 32116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 32216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // After parsing the base expression we could either have a parenthesized 32316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // memory address or not. If not, return now. If so, eat the (. 32416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().isNot(AsmToken::LParen)) { 325c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar // Unless we have a segment register, treat this as an immediate. 326c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar if (SegReg) 327c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar Op = X86Operand::CreateMem(SegReg, Disp, 0, 0, 1); 328c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar else 329c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar Op = X86Operand::CreateImm(Disp); 33016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return false; 33116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 33216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 33316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Eat the '('. 33416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar getLexer().Lex(); 33516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 33616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 33716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 33816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // If we reached here, then we just ate the ( of the memory operand. Process 33916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // the rest of the memory operand. 340022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar unsigned BaseReg = 0, IndexReg = 0, Scale = 1; 34116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 3427b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby if (getLexer().is(AsmToken::Percent)) { 34316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (ParseRegister(Op)) 34416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return true; 34516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar BaseReg = Op.getReg(); 34616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 34716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 34816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().is(AsmToken::Comma)) { 34916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar getLexer().Lex(); // Eat the comma. 35016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 35116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Following the comma we should have either an index register, or a scale 35216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // value. We don't support the later form, but we want to parse it 35316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // correctly. 35416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // 35516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Not that even though it would be completely consistent to support syntax 35616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // like "1(%eax,,1)", the assembler doesn't. 3577b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby if (getLexer().is(AsmToken::Percent)) { 35816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (ParseRegister(Op)) 35916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return true; 36016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar IndexReg = Op.getReg(); 36116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 36216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().isNot(AsmToken::RParen)) { 36316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Parse the scale amount: 36416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // ::= ',' [scale-expression] 36516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().isNot(AsmToken::Comma)) 36616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return true; 36716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar getLexer().Lex(); // Eat the comma. 36816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 36916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().isNot(AsmToken::RParen)) { 37016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar SMLoc Loc = getLexer().getTok().getLoc(); 37116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 37216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar int64_t ScaleVal; 37316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getParser().ParseAbsoluteExpression(ScaleVal)) 37416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return true; 37516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 37616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Validate the scale amount. 37716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8) 37816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return Error(Loc, "scale factor in address must be 1, 2, 4 or 8"); 37916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Scale = (unsigned)ScaleVal; 38016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 38116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 38216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } else if (getLexer().isNot(AsmToken::RParen)) { 38316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Otherwise we have the unsupported form of a scale amount without an 38416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // index. 38516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar SMLoc Loc = getLexer().getTok().getLoc(); 38616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 38716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar int64_t Value; 38816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getParser().ParseAbsoluteExpression(Value)) 38916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return true; 39016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 39116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return Error(Loc, "cannot have scale factor without index register"); 39216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 39316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 39416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 39516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Ok, we've eaten the memory operand, verify we have a ')' and eat it too. 39616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().isNot(AsmToken::RParen)) 39716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return Error(getLexer().getTok().getLoc(), 39816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar "unexpected token in memory operand"); 39916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar getLexer().Lex(); // Eat the ')'. 40016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 40116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Op = X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale); 40216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return false; 403dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar} 404dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar 405f007e853e26845cd6866b52d646455fc69f4e0afChris Lattnerbool X86ATTAsmParser::ParseInstruction(const StringRef &Name, 406f007e853e26845cd6866b52d646455fc69f4e0afChris Lattner SMLoc NameLoc, MCInst &Inst) { 4072724915c171b08fa9f7f9e54a46ea81708d9c5b2Daniel Dunbar SmallVector<X86Operand, 8> Operands; 40820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 40920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Operands.push_back(X86Operand::CreateToken(Name)); 41016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 411a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar SMLoc Loc = getLexer().getTok().getLoc(); 41216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().isNot(AsmToken::EndOfStatement)) { 4130db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar 4140db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar // Parse '*' modifier. 4150db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar if (getLexer().is(AsmToken::Star)) { 4160db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar getLexer().Lex(); // Eat the star. 4170db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar Operands.push_back(X86Operand::CreateToken("*")); 4180db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar } 4190db68f4e3a8be1641dbba72a41baa6ff1b5dd6afDaniel Dunbar 42016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Read the first operand. 42116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Operands.push_back(X86Operand()); 42216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (ParseOperand(Operands.back())) 42316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return true; 42416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 42516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar while (getLexer().is(AsmToken::Comma)) { 42616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar getLexer().Lex(); // Eat the comma. 42716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 42816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Parse and remember the operand. 42916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Operands.push_back(X86Operand()); 43016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (ParseOperand(Operands.back())) 43116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return true; 43216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 43316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 43416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 43520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (!MatchInstruction(Operands, Inst)) 436a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar return false; 437a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 438a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar // FIXME: We should give nicer diagnostics about the exact failure. 439a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 440c22e0b2443afdedb6d9b225b938ad404d63cdbe6Daniel Dunbar Error(Loc, "unrecognized instruction"); 441c22e0b2443afdedb6d9b225b938ad404d63cdbe6Daniel Dunbar return true; 442a3af370dc12f6d5100da5d614ab0a62da135569aDaniel Dunbar} 443a3af370dc12f6d5100da5d614ab0a62da135569aDaniel Dunbar 4449c656450d65034c4cd3597fff61ef17376cff090Kevin Enderbybool X86ATTAsmParser::ParseDirective(AsmToken DirectiveID) { 4459c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby StringRef IDVal = DirectiveID.getIdentifier(); 4469c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby if (IDVal == ".word") 4479c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby return ParseDirectiveWord(2, DirectiveID.getLoc()); 4489c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby return true; 4499c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby} 4509c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby 4519c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby/// ParseDirectiveWord 4529c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby/// ::= .word [ expression (, expression)* ] 4539c656450d65034c4cd3597fff61ef17376cff090Kevin Enderbybool X86ATTAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { 4549c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) { 4559c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby for (;;) { 4569c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby const MCExpr *Value; 4579c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby if (getParser().ParseExpression(Value)) 4589c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby return true; 4599c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby 4609c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby getParser().getStreamer().EmitValue(Value, Size); 4619c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby 4629c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby if (getLexer().is(AsmToken::EndOfStatement)) 4639c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby break; 4649c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby 4659c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby // FIXME: Improve diagnostic. 4669c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby if (getLexer().isNot(AsmToken::Comma)) 4679c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby return Error(L, "unexpected token in directive"); 4689c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby getLexer().Lex(); 4699c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby } 4709c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby } 4719c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby 4729c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby getLexer().Lex(); 4739c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby return false; 4749c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby} 4759c656450d65034c4cd3597fff61ef17376cff090Kevin Enderby 476092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar// Force static initialization. 477092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbarextern "C" void LLVMInitializeX86AsmParser() { 4780c795d61878156817cedbac51ec2921f2634c1a5Daniel Dunbar RegisterAsmParser<X86ATTAsmParser> X(TheX86_32Target); 4790c795d61878156817cedbac51ec2921f2634c1a5Daniel Dunbar RegisterAsmParser<X86ATTAsmParser> Y(TheX86_64Target); 480092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar} 4810e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar 4820e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar#include "X86GenAsmMatcher.inc" 483