X86AsmParser.cpp revision c6b79ac88e52367dd2afdf03b1be81b10345c0bb
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 bool MatchInstruction(const StringRef &Name, 30c3c35b17218248f9b4786a6125bf9719e536eeb2Chris Lattner SmallVectorImpl<X86Operand> &Operands, 3116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar MCInst &Inst); 32092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar 3316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar MCAsmParser &getParser() const { return Parser; } 34a2edbabcb86f213eca6daeda5d801f8c7b1e44b2Daniel Dunbar 3516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar MCAsmLexer &getLexer() const { return Parser.getLexer(); } 3616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 3716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); } 3816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 3916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); } 4016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 4116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar bool ParseRegister(X86Operand &Op); 4216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 4316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar bool ParseOperand(X86Operand &Op); 4416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 4516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar bool ParseMemOperand(X86Operand &Op); 460e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar 470e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar /// @name Auto-generated Match Functions 480e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar /// { 490e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar 500e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar bool MatchRegisterName(const StringRef &Name, unsigned &RegNo); 510e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar 520e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar /// } 5316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 5416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbarpublic: 5516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar X86ATTAsmParser(const Target &T, MCAsmParser &_Parser) 5616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar : TargetAsmParser(T), Parser(_Parser) {} 5716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 5816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar virtual bool ParseInstruction(const StringRef &Name, MCInst &Inst); 5916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar}; 6037dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner 6137dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner} // end anonymous namespace 6237dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner 6337dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner 6437dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattnernamespace { 6516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 6616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar/// X86Operand - Instances of this class represent a parsed X86 machine 6716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar/// instruction. 6816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbarstruct X86Operand { 6916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar enum { 7016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Register, 7116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Immediate, 7216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Memory 7316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } Kind; 7416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 7516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar union { 7616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar struct { 7716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar unsigned RegNo; 7816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } Reg; 7916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 8016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar struct { 8116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar MCValue Val; 8216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } Imm; 8316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 8416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar struct { 8516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar unsigned SegReg; 8616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar MCValue Disp; 8716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar unsigned BaseReg; 8816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar unsigned IndexReg; 8916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar unsigned Scale; 9016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } Mem; 91dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar }; 9216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 9316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar unsigned getReg() const { 9416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar assert(Kind == Register && "Invalid access!"); 9516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return Reg.RegNo; 9616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 9716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 9816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar static X86Operand CreateReg(unsigned RegNo) { 9916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar X86Operand Res; 10016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Res.Kind = Register; 10116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Res.Reg.RegNo = RegNo; 10216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return Res; 10316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 10416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar static X86Operand CreateImm(MCValue Val) { 10516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar X86Operand Res; 10616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Res.Kind = Immediate; 10716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Res.Imm.Val = Val; 10816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return Res; 10916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 11016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar static X86Operand CreateMem(unsigned SegReg, MCValue Disp, unsigned BaseReg, 11116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar unsigned IndexReg, unsigned Scale) { 11216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // If there is no index register, we should never have a scale, and we 11316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // should always have a scale (in {1,2,4,8}) if we do. 11416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar assert(((Scale == 0 && !IndexReg) || 11516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar (IndexReg && (Scale == 1 || Scale == 2 || 11616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Scale == 4 || Scale == 8))) && 11716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar "Invalid scale!"); 11816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar X86Operand Res; 11916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Res.Kind = Memory; 12016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Res.Mem.SegReg = SegReg; 12116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Res.Mem.Disp = Disp; 12216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Res.Mem.BaseReg = BaseReg; 12316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Res.Mem.IndexReg = IndexReg; 12416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Res.Mem.Scale = Scale; 12516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return Res; 12616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 12716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar}; 12816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 12937dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner} // end anonymous namespace. 13016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 13116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 13216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbarbool X86ATTAsmParser::ParseRegister(X86Operand &Op) { 13337dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner const AsmToken &Tok = getLexer().getTok(); 1340e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar assert(Tok.is(AsmToken::Register) && "Invalid token kind!"); 13516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 1360e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar // FIXME: Validate register for the current architecture; we have to do 1370e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar // validation later, so maybe there is no need for this here. 1380e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar unsigned RegNo; 1390e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar assert(Tok.getString().startswith("%") && "Invalid register name!"); 1400e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar if (MatchRegisterName(Tok.getString().substr(1), RegNo)) 1410e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar return Error(Tok.getLoc(), "invalid register name"); 1420e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar 1430e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar Op = X86Operand::CreateReg(RegNo); 14416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar getLexer().Lex(); // Eat register token. 14516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 14616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return false; 147092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar} 148092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar 149dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbarbool X86ATTAsmParser::ParseOperand(X86Operand &Op) { 15016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar switch (getLexer().getKind()) { 15116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar default: 15216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return ParseMemOperand(Op); 15316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar case AsmToken::Register: 15416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // FIXME: if a segment register, this could either be just the seg reg, or 15516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // the start of a memory operand. 15616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return ParseRegister(Op); 15716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar case AsmToken::Dollar: { 15816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // $42 -> immediate. 15916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar getLexer().Lex(); 16016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar MCValue Val; 16116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getParser().ParseRelocatableExpression(Val)) 16216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return true; 16316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Op = X86Operand::CreateImm(Val); 16416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return false; 16516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 16637dfdecafdaabc87d3a9dcfc8c33a2308af2763cChris Lattner case AsmToken::Star: 16716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar getLexer().Lex(); // Eat the star. 16816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 16916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().is(AsmToken::Register)) { 17016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (ParseRegister(Op)) 17116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return true; 17216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } else if (ParseMemOperand(Op)) 17316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return true; 17416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 17516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // FIXME: Note the '*' in the operand for use by the matcher. 17616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return false; 17716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 17816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar} 17916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 18016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar/// ParseMemOperand: segment: disp(basereg, indexreg, scale) 18116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbarbool X86ATTAsmParser::ParseMemOperand(X86Operand &Op) { 18216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // FIXME: If SegReg ':' (e.g. %gs:), eat and remember. 18316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar unsigned SegReg = 0; 18416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 18516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // We have to disambiguate a parenthesized expression "(4+5)" from the start 18616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)". The 18716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // only way to do this without lookahead is to eat the ( and see what is after 18816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // it. 18916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar MCValue Disp = MCValue::get(0, 0, 0); 19016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().isNot(AsmToken::LParen)) { 19116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getParser().ParseRelocatableExpression(Disp)) return true; 19216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 19316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // After parsing the base expression we could either have a parenthesized 19416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // memory address or not. If not, return now. If so, eat the (. 19516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().isNot(AsmToken::LParen)) { 19616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Op = X86Operand::CreateMem(SegReg, Disp, 0, 0, 0); 19716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return false; 19816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 19916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 20016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Eat the '('. 20116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar getLexer().Lex(); 20216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } else { 20316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Okay, we have a '('. We don't know if this is an expression or not, but 20416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // so we have to eat the ( to see beyond it. 20516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar getLexer().Lex(); // Eat the '('. 20616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 20716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().is(AsmToken::Register) || getLexer().is(AsmToken::Comma)) { 20816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Nothing to do here, fall into the code below with the '(' part of the 20916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // memory operand consumed. 21016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } else { 21116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // It must be an parenthesized expression, parse it now. 21216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getParser().ParseParenRelocatableExpression(Disp)) 21316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return true; 21416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 21516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // After parsing the base expression we could either have a parenthesized 21616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // memory address or not. If not, return now. If so, eat the (. 21716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().isNot(AsmToken::LParen)) { 21816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Op = X86Operand::CreateMem(SegReg, Disp, 0, 0, 0); 21916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return false; 22016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 22116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 22216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Eat the '('. 22316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar getLexer().Lex(); 22416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 22516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 22616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 22716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // If we reached here, then we just ate the ( of the memory operand. Process 22816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // the rest of the memory operand. 22916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar unsigned BaseReg = 0, IndexReg = 0, Scale = 0; 23016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 23116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().is(AsmToken::Register)) { 23216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (ParseRegister(Op)) 23316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return true; 23416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar BaseReg = Op.getReg(); 23516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 23616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 23716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().is(AsmToken::Comma)) { 23816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar getLexer().Lex(); // Eat the comma. 23916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 24016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Following the comma we should have either an index register, or a scale 24116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // value. We don't support the later form, but we want to parse it 24216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // correctly. 24316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // 24416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Not that even though it would be completely consistent to support syntax 24516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // like "1(%eax,,1)", the assembler doesn't. 24616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().is(AsmToken::Register)) { 24716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (ParseRegister(Op)) 24816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return true; 24916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar IndexReg = Op.getReg(); 25016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Scale = 1; // If not specified, the scale defaults to 1. 25116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 25216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().isNot(AsmToken::RParen)) { 25316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Parse the scale amount: 25416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // ::= ',' [scale-expression] 25516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().isNot(AsmToken::Comma)) 25616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return true; 25716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar getLexer().Lex(); // Eat the comma. 25816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 25916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().isNot(AsmToken::RParen)) { 26016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar SMLoc Loc = getLexer().getTok().getLoc(); 26116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 26216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar int64_t ScaleVal; 26316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getParser().ParseAbsoluteExpression(ScaleVal)) 26416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return true; 26516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 26616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Validate the scale amount. 26716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8) 26816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return Error(Loc, "scale factor in address must be 1, 2, 4 or 8"); 26916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Scale = (unsigned)ScaleVal; 27016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 27116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 27216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } else if (getLexer().isNot(AsmToken::RParen)) { 27316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Otherwise we have the unsupported form of a scale amount without an 27416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // index. 27516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar SMLoc Loc = getLexer().getTok().getLoc(); 27616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 27716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar int64_t Value; 27816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getParser().ParseAbsoluteExpression(Value)) 27916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return true; 28016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 28116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return Error(Loc, "cannot have scale factor without index register"); 28216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 28316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 28416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 28516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Ok, we've eaten the memory operand, verify we have a ')' and eat it too. 28616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().isNot(AsmToken::RParen)) 28716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return Error(getLexer().getTok().getLoc(), 28816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar "unexpected token in memory operand"); 28916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar getLexer().Lex(); // Eat the ')'. 29016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 29116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Op = X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale); 29216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return false; 293dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar} 294dbd692a66e6a5f60ec3ff120ed27ae3a918c375fDaniel Dunbar 29516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbarbool X86ATTAsmParser::ParseInstruction(const StringRef &Name, MCInst &Inst) { 296c3c35b17218248f9b4786a6125bf9719e536eeb2Chris Lattner SmallVector<X86Operand, 3> Operands; 29716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 298a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar SMLoc Loc = getLexer().getTok().getLoc(); 29916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (getLexer().isNot(AsmToken::EndOfStatement)) { 30016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Read the first operand. 30116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Operands.push_back(X86Operand()); 30216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (ParseOperand(Operands.back())) 30316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return true; 30416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 30516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar while (getLexer().is(AsmToken::Comma)) { 30616cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar getLexer().Lex(); // Eat the comma. 30716cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 30816cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar // Parse and remember the operand. 30916cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar Operands.push_back(X86Operand()); 31016cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar if (ParseOperand(Operands.back())) 31116cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar return true; 31216cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 31316cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar } 31416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar 315a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar if (!MatchInstruction(Name, Operands, Inst)) 316a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar return false; 317a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 318a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar // FIXME: We should give nicer diagnostics about the exact failure. 319a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 320a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar // FIXME: For now we just treat unrecognized instructions as "warnings". 321a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar Warning(Loc, "unrecognized instruction"); 322a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 323a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar return false; 324a3af370dc12f6d5100da5d614ab0a62da135569aDaniel Dunbar} 325a3af370dc12f6d5100da5d614ab0a62da135569aDaniel Dunbar 326092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar// Force static initialization. 327092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbarextern "C" void LLVMInitializeX86AsmParser() { 3280c795d61878156817cedbac51ec2921f2634c1a5Daniel Dunbar RegisterAsmParser<X86ATTAsmParser> X(TheX86_32Target); 3290c795d61878156817cedbac51ec2921f2634c1a5Daniel Dunbar RegisterAsmParser<X86ATTAsmParser> Y(TheX86_64Target); 330092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar} 3310e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar 332a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar// FIXME: These should come from tblgen. 333a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 334a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar// Match_X86_Op_GR8 335a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbarstatic bool 336a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel DunbarMatch_X86_Op_GR8(const X86Operand &Op, MCOperand *MCOps, unsigned NumOps) { 337a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar assert(NumOps == 1 && "Invalid number of ops!"); 338a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 339a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar // FIXME: Match correct registers. 340a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar if (Op.Kind != X86Operand::Register) 341a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar return true; 342a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 343a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar MCOps[0].MakeReg(Op.getReg()); 344a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar return false; 345a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar} 346a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 347a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar#define DUMMY(name) \ 348a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar static bool Match_X86_Op_##name(const X86Operand &Op, \ 349a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar MCOperand *MCOps, \ 350a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar unsigned NumMCOps) { \ 351a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar return true; \ 352a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar } 353a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 354a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel DunbarDUMMY(FR32) 355a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel DunbarDUMMY(FR64) 356a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel DunbarDUMMY(GR16) 357a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel DunbarDUMMY(GR32) 358a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel DunbarDUMMY(GR32_NOREX) 359a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel DunbarDUMMY(GR64) 360a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel DunbarDUMMY(GR8_NOREX) 361a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel DunbarDUMMY(RST) 362a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel DunbarDUMMY(VR128) 363a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel DunbarDUMMY(VR64) 364a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel DunbarDUMMY(brtarget) 365a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel DunbarDUMMY(brtarget8) 366a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel DunbarDUMMY(f128mem) 367a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel DunbarDUMMY(f32mem) 368a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel DunbarDUMMY(f64mem) 369a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel DunbarDUMMY(f80mem) 370a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel DunbarDUMMY(i128mem) 371a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel DunbarDUMMY(i16i8imm) 372a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel DunbarDUMMY(i16imm) 373a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel DunbarDUMMY(i16mem) 374a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel DunbarDUMMY(i32i8imm) 375a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel DunbarDUMMY(i32imm_pcrel) 376a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel DunbarDUMMY(i32imm) 377a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel DunbarDUMMY(i32mem) 378a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel DunbarDUMMY(i64i32imm_pcrel) 379a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel DunbarDUMMY(i64i32imm) 380a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel DunbarDUMMY(i64i8imm) 381a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel DunbarDUMMY(i64imm) 382a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel DunbarDUMMY(i64mem) 383a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel DunbarDUMMY(i8imm) 384a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel DunbarDUMMY(i8mem_NOREX) 385a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel DunbarDUMMY(i8mem) 386a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel DunbarDUMMY(lea32mem) 387a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel DunbarDUMMY(lea64_32mem) 388a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel DunbarDUMMY(lea64mem) 389a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel DunbarDUMMY(sdmem) 390a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel DunbarDUMMY(ssmem) 391a027d222e18ea9028e9e12ae2f5cd566889b599aDaniel Dunbar 3920e2771f4c4a6e1ffc664eb23487087f824340255Daniel Dunbar#include "X86GenAsmMatcher.inc" 393