X86AsmParser.cpp revision 5fe6338ac859707f797bf6db6d043bb5f4d944a1
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" 15a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar#include "llvm/MC/MCInst.h" 1616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar#include "llvm/MC/MCValue.h" 1716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar#include "llvm/Support/SourceMgr.h" 18092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar#include "llvm/Target/TargetRegistry.h" 19092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar#include "llvm/Target/TargetAsmParser.h" 20092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbarusing namespace llvm; 21092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar 22092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbarnamespace { 23c6b79ac88e52367dd2afdf03b1be81b10345c0bbBenjamin Kramerstruct X86Operand; 24092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar 2516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbarclass X86ATTAsmParser : public TargetAsmParser { 2616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar MCAsmParser &Parser; 27a2edbabcb86f213eca6daeda5d801f8c7b1e44b2Daniel Dunbar 2816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbarprivate: 2916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar MCAsmParser &getParser() const { return Parser; } 30a2edbabcb86f213eca6daeda5d801f8c7b1e44b2Daniel Dunbar 3116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar MCAsmLexer &getLexer() const { return Parser.getLexer(); } 3216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 3316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); } 3416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 3516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); } 3616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 3716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar bool ParseRegister(X86Operand &Op); 3816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 3916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar bool ParseOperand(X86Operand &Op); 4016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 4116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar bool ParseMemOperand(X86Operand &Op); 420e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar 430e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar /// @name Auto-generated Match Functions 440e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar /// { 450e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar 4620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar bool MatchInstruction(SmallVectorImpl<X86Operand> &Operands, 4720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar MCInst &Inst); 4820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 49245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar /// MatchRegisterName - Match the given string to a register name, or 0 if 50245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar /// there is no match. 51245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar unsigned MatchRegisterName(const StringRef &Name); 520e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar 530e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar /// } 5416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 5516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbarpublic: 5616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar X86ATTAsmParser(const Target &T, MCAsmParser &_Parser) 5716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar : TargetAsmParser(T), Parser(_Parser) {} 5816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 5916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar virtual bool ParseInstruction(const StringRef &Name, MCInst &Inst); 6016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar}; 6137dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner 6237dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner} // end anonymous namespace 6337dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner 6437dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner 6537dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattnernamespace { 6616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 6716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar/// X86Operand - Instances of this class represent a parsed X86 machine 6816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar/// instruction. 6916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbarstruct X86Operand { 7016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar enum { 7120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Token, 7216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Register, 7316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Immediate, 7416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Memory 7516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } Kind; 7616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 7716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar union { 7816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar struct { 7920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar const char *Data; 8020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar unsigned Length; 8120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } Tok; 8220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 8320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar struct { 8416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar unsigned RegNo; 8516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } Reg; 8616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 8716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar struct { 8816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar MCValue Val; 8916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } Imm; 9016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 9116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar struct { 9216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar unsigned SegReg; 9316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar MCValue Disp; 9416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar unsigned BaseReg; 9516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar unsigned IndexReg; 9616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar unsigned Scale; 9716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } Mem; 98dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar }; 9916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 10020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar StringRef getToken() const { 10120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar assert(Kind == Token && "Invalid access!"); 10220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar return StringRef(Tok.Data, Tok.Length); 10320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 10420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 10516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar unsigned getReg() const { 10616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar assert(Kind == Register && "Invalid access!"); 10716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return Reg.RegNo; 10816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 10916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 110022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar const MCValue &getImm() const { 111022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar assert(Kind == Immediate && "Invalid access!"); 112022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar return Imm.Val; 113022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar } 114022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar 115022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar const MCValue &getMemDisp() const { 116022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar assert(Kind == Memory && "Invalid access!"); 117022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar return Mem.Disp; 118022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar } 119022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar unsigned getMemSegReg() const { 120022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar assert(Kind == Memory && "Invalid access!"); 121022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar return Mem.SegReg; 122022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar } 123022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar unsigned getMemBaseReg() const { 124022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar assert(Kind == Memory && "Invalid access!"); 125022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar return Mem.BaseReg; 126022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar } 127022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar unsigned getMemIndexReg() const { 128022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar assert(Kind == Memory && "Invalid access!"); 129022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar return Mem.IndexReg; 130022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar } 131022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar unsigned getMemScale() const { 132022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar assert(Kind == Memory && "Invalid access!"); 133022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar return Mem.Scale; 134022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar } 135022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar 136a3741fa28b1a397ebfd623ef9d14e978df94ce47Daniel Dunbar bool isToken() const {return Kind == Token; } 13720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 13820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar bool isImm() const { return Kind == Immediate; } 13920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 1405fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar bool isImmSExt8() const { 1415fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar // Accept immediates which fit in 8 bits when sign extended, and 1425fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar // non-absolute immediates. 1435fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar if (!isImm()) 1445fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar return false; 1455fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar 1465fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar if (!getImm().isAbsolute()) 1475fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar return true; 1485fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar 1495fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar int64_t Value = getImm().getConstant(); 1505fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar return Value == (int64_t) (int8_t) Value; 1515fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar } 1525fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar 15320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar bool isMem() const { return Kind == Memory; } 15420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 15520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar bool isReg() const { return Kind == Register; } 15620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 15720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar void addRegOperands(MCInst &Inst, unsigned N) { 15820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar assert(N == 1 && "Invalid number of operands!"); 15920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Inst.addOperand(MCOperand::CreateReg(getReg())); 16020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 16120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 16220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar void addImmOperands(MCInst &Inst, unsigned N) { 16320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar assert(N == 1 && "Invalid number of operands!"); 16420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Inst.addOperand(MCOperand::CreateMCValue(getImm())); 16520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 16620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 1675fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar void addImmSExt8Operands(MCInst &Inst, unsigned N) { 1685fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar // FIXME: Support user customization of the render method. 1695fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar assert(N == 1 && "Invalid number of operands!"); 1705fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar Inst.addOperand(MCOperand::CreateMCValue(getImm())); 1715fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar } 1725fe6338ac859707f797bf6db6d043bb5f4d944a1Daniel Dunbar 17320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar void addMemOperands(MCInst &Inst, unsigned N) { 17420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar assert((N == 4 || N == 5) && "Invalid number of operands!"); 17520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 17620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Inst.addOperand(MCOperand::CreateReg(getMemBaseReg())); 17720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Inst.addOperand(MCOperand::CreateImm(getMemScale())); 17820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Inst.addOperand(MCOperand::CreateReg(getMemIndexReg())); 17920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Inst.addOperand(MCOperand::CreateMCValue(getMemDisp())); 18020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 18120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar // FIXME: What a hack. 18220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (N == 5) 18320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Inst.addOperand(MCOperand::CreateReg(getMemSegReg())); 18420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 18520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 18620927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar static X86Operand CreateToken(StringRef Str) { 18720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar X86Operand Res; 18820927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Res.Kind = Token; 18920927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Res.Tok.Data = Str.data(); 19020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Res.Tok.Length = Str.size(); 19120927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar return Res; 19220927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar } 19320927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 19416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar static X86Operand CreateReg(unsigned RegNo) { 19516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar X86Operand Res; 19616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Res.Kind = Register; 19716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Res.Reg.RegNo = RegNo; 19816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return Res; 19916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 20020927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 20116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar static X86Operand CreateImm(MCValue Val) { 20216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar X86Operand Res; 20316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Res.Kind = Immediate; 20416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Res.Imm.Val = Val; 20516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return Res; 20616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 20720927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 20816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar static X86Operand CreateMem(unsigned SegReg, MCValue Disp, unsigned BaseReg, 20916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar unsigned IndexReg, unsigned Scale) { 210c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar // We should never just have a displacement, that would be an immediate. 211c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!"); 212c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar 213022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar // The scale should always be one of {1,2,4,8}. 214022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) && 21516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar "Invalid scale!"); 21616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar X86Operand Res; 21716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Res.Kind = Memory; 21816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Res.Mem.SegReg = SegReg; 21916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Res.Mem.Disp = Disp; 22016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Res.Mem.BaseReg = BaseReg; 22116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Res.Mem.IndexReg = IndexReg; 22216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Res.Mem.Scale = Scale; 22316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return Res; 22416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 22516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar}; 22616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 22737dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner} // end anonymous namespace. 22816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 22916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 23016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbarbool X86ATTAsmParser::ParseRegister(X86Operand &Op) { 23137dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner const AsmToken &Tok = getLexer().getTok(); 2320e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar assert(Tok.is(AsmToken::Register) && "Invalid token kind!"); 23316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 2340e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar // FIXME: Validate register for the current architecture; we have to do 2350e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar // validation later, so maybe there is no need for this here. 2360e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar unsigned RegNo; 2370e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar assert(Tok.getString().startswith("%") && "Invalid register name!"); 238245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar 239245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar RegNo = MatchRegisterName(Tok.getString().substr(1)); 240245f05843f7f17406f394696e7330950e6d88e6dDaniel Dunbar if (RegNo == 0) 2410e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar return Error(Tok.getLoc(), "invalid register name"); 2420e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar 2430e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar Op = X86Operand::CreateReg(RegNo); 24416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar getLexer().Lex(); // Eat register token. 24516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 24616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return false; 247092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar} 248092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar 249dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbarbool X86ATTAsmParser::ParseOperand(X86Operand &Op) { 25016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar switch (getLexer().getKind()) { 25116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar default: 25216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return ParseMemOperand(Op); 25316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar case AsmToken::Register: 25416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // FIXME: if a segment register, this could either be just the seg reg, or 25516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // the start of a memory operand. 25616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return ParseRegister(Op); 25716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar case AsmToken::Dollar: { 25816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // $42 -> immediate. 25916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar getLexer().Lex(); 26016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar MCValue Val; 26116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getParser().ParseRelocatableExpression(Val)) 26216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return true; 26316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Op = X86Operand::CreateImm(Val); 26416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return false; 26516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 26637dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner case AsmToken::Star: 26716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar getLexer().Lex(); // Eat the star. 26816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 26916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().is(AsmToken::Register)) { 27016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (ParseRegister(Op)) 27116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return true; 27216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } else if (ParseMemOperand(Op)) 27316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return true; 27416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 27516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // FIXME: Note the '*' in the operand for use by the matcher. 27616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return false; 27716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 27816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar} 27916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 28016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar/// ParseMemOperand: segment: disp(basereg, indexreg, scale) 28116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbarbool X86ATTAsmParser::ParseMemOperand(X86Operand &Op) { 28216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // FIXME: If SegReg ':' (e.g. %gs:), eat and remember. 28316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar unsigned SegReg = 0; 28416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 28516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // We have to disambiguate a parenthesized expression "(4+5)" from the start 28616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)". The 28716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // only way to do this without lookahead is to eat the ( and see what is after 28816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // it. 28916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar MCValue Disp = MCValue::get(0, 0, 0); 29016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().isNot(AsmToken::LParen)) { 29116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getParser().ParseRelocatableExpression(Disp)) return true; 29216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 29316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // After parsing the base expression we could either have a parenthesized 29416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // memory address or not. If not, return now. If so, eat the (. 29516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().isNot(AsmToken::LParen)) { 296c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar // Unless we have a segment register, treat this as an immediate. 297c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar if (SegReg) 298c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar Op = X86Operand::CreateMem(SegReg, Disp, 0, 0, 1); 299c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar else 300c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar Op = X86Operand::CreateImm(Disp); 30116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return false; 30216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 30316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 30416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Eat the '('. 30516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar getLexer().Lex(); 30616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } else { 30716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Okay, we have a '('. We don't know if this is an expression or not, but 30816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // so we have to eat the ( to see beyond it. 30916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar getLexer().Lex(); // Eat the '('. 31016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 31116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().is(AsmToken::Register) || getLexer().is(AsmToken::Comma)) { 31216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Nothing to do here, fall into the code below with the '(' part of the 31316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // memory operand consumed. 31416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } else { 31516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // It must be an parenthesized expression, parse it now. 31616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getParser().ParseParenRelocatableExpression(Disp)) 31716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return true; 31816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 31916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // After parsing the base expression we could either have a parenthesized 32016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // memory address or not. If not, return now. If so, eat the (. 32116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().isNot(AsmToken::LParen)) { 322c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar // Unless we have a segment register, treat this as an immediate. 323c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar if (SegReg) 324c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar Op = X86Operand::CreateMem(SegReg, Disp, 0, 0, 1); 325c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar else 326c09e411102878c7f01ef707c2ac52eb3c76ab77bDaniel Dunbar Op = X86Operand::CreateImm(Disp); 32716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return false; 32816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 32916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 33016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Eat the '('. 33116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar getLexer().Lex(); 33216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 33316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 33416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 33516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // If we reached here, then we just ate the ( of the memory operand. Process 33616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // the rest of the memory operand. 337022e2a84a867ba73fd0e6b89f61e56396f22620dDaniel Dunbar unsigned BaseReg = 0, IndexReg = 0, Scale = 1; 33816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 33916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().is(AsmToken::Register)) { 34016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (ParseRegister(Op)) 34116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return true; 34216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar BaseReg = Op.getReg(); 34316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 34416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 34516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().is(AsmToken::Comma)) { 34616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar getLexer().Lex(); // Eat the comma. 34716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 34816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Following the comma we should have either an index register, or a scale 34916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // value. We don't support the later form, but we want to parse it 35016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // correctly. 35116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // 35216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Not that even though it would be completely consistent to support syntax 35316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // like "1(%eax,,1)", the assembler doesn't. 35416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().is(AsmToken::Register)) { 35516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (ParseRegister(Op)) 35616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return true; 35716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar IndexReg = Op.getReg(); 35816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 35916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().isNot(AsmToken::RParen)) { 36016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Parse the scale amount: 36116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // ::= ',' [scale-expression] 36216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().isNot(AsmToken::Comma)) 36316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return true; 36416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar getLexer().Lex(); // Eat the comma. 36516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 36616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().isNot(AsmToken::RParen)) { 36716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar SMLoc Loc = getLexer().getTok().getLoc(); 36816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 36916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar int64_t ScaleVal; 37016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getParser().ParseAbsoluteExpression(ScaleVal)) 37116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return true; 37216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 37316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Validate the scale amount. 37416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8) 37516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return Error(Loc, "scale factor in address must be 1, 2, 4 or 8"); 37616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Scale = (unsigned)ScaleVal; 37716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 37816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 37916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } else if (getLexer().isNot(AsmToken::RParen)) { 38016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Otherwise we have the unsupported form of a scale amount without an 38116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // index. 38216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar SMLoc Loc = getLexer().getTok().getLoc(); 38316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 38416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar int64_t Value; 38516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getParser().ParseAbsoluteExpression(Value)) 38616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return true; 38716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 38816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return Error(Loc, "cannot have scale factor without index register"); 38916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 39016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 39116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 39216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Ok, we've eaten the memory operand, verify we have a ')' and eat it too. 39316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().isNot(AsmToken::RParen)) 39416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return Error(getLexer().getTok().getLoc(), 39516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar "unexpected token in memory operand"); 39616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar getLexer().Lex(); // Eat the ')'. 39716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 39816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Op = X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale); 39916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return false; 400dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar} 401dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar 40216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbarbool X86ATTAsmParser::ParseInstruction(const StringRef &Name, MCInst &Inst) { 4032724915c171b08fa9f7f9e54a46ea81708d9c5b2Daniel Dunbar SmallVector<X86Operand, 8> Operands; 40420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar 40520927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar Operands.push_back(X86Operand::CreateToken(Name)); 40616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 407a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar SMLoc Loc = getLexer().getTok().getLoc(); 40816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().isNot(AsmToken::EndOfStatement)) { 40916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Read the first operand. 41016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Operands.push_back(X86Operand()); 41116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (ParseOperand(Operands.back())) 41216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return true; 41316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 41416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar while (getLexer().is(AsmToken::Comma)) { 41516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar getLexer().Lex(); // Eat the comma. 41616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 41716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Parse and remember the operand. 41816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Operands.push_back(X86Operand()); 41916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (ParseOperand(Operands.back())) 42016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return true; 42116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 42216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 42316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 42420927f26fcd7d0394bc60c58c61d879a83adac0dDaniel Dunbar if (!MatchInstruction(Operands, Inst)) 425a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar return false; 426a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 427a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar // FIXME: We should give nicer diagnostics about the exact failure. 428a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 429a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar // FIXME: For now we just treat unrecognized instructions as "warnings". 430a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar Warning(Loc, "unrecognized instruction"); 431a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 432a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar return false; 433a3af370dc12f6d5100da5d614ab0a62da135569aDaniel Dunbar} 434a3af370dc12f6d5100da5d614ab0a62da135569aDaniel Dunbar 435092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar// Force static initialization. 436092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbarextern "C" void LLVMInitializeX86AsmParser() { 4370c795d61878156817cedbac51ec2921f2634c1a5Daniel Dunbar RegisterAsmParser<X86ATTAsmParser> X(TheX86_32Target); 4380c795d61878156817cedbac51ec2921f2634c1a5Daniel Dunbar RegisterAsmParser<X86ATTAsmParser> Y(TheX86_64Target); 439092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar} 4400e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar 4410e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar#include "X86GenAsmMatcher.inc" 442