diff options
Diffstat (limited to 'lib/Target/X86/AsmParser/X86AsmParser.cpp')
-rw-r--r-- | lib/Target/X86/AsmParser/X86AsmParser.cpp | 239 |
1 files changed, 130 insertions, 109 deletions
diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp index c4ae5d2..7a9218e 100644 --- a/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -11,12 +11,12 @@ #include "X86.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Twine.h" -#include "llvm/MC/MCAsmLexer.h" -#include "llvm/MC/MCAsmParser.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" -#include "llvm/MC/MCParsedAsmOperand.h" +#include "llvm/MC/MCParser/MCAsmLexer.h" +#include "llvm/MC/MCParser/MCAsmParser.h" +#include "llvm/MC/MCParser/MCParsedAsmOperand.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Target/TargetRegistry.h" #include "llvm/Target/TargetAsmParser.h" @@ -37,11 +37,10 @@ private: bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); } - bool ParseRegister(X86Operand &Op); + bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); - bool ParseOperand(X86Operand &Op); - - bool ParseMemOperand(X86Operand &Op); + X86Operand *ParseOperand(); + X86Operand *ParseMemOperand(); bool ParseDirectiveWord(unsigned Size, SMLoc L); @@ -51,10 +50,6 @@ private: bool MatchInstruction(const SmallVectorImpl<MCParsedAsmOperand*> &Operands, MCInst &Inst); - /// MatchRegisterName - Match the given string to a register name, or 0 if - /// there is no match. - unsigned MatchRegisterName(const StringRef &Name); - /// } public: @@ -69,19 +64,27 @@ public: } // end anonymous namespace +/// @name Auto-generated Match Functions +/// { + +static unsigned MatchRegisterName(const StringRef &Name); + +/// } namespace { /// X86Operand - Instances of this class represent a parsed X86 machine /// instruction. struct X86Operand : public MCParsedAsmOperand { - enum { + enum KindTy { Token, Register, Immediate, Memory } Kind; + SMLoc StartLoc, EndLoc; + union { struct { const char *Data; @@ -105,6 +108,14 @@ struct X86Operand : public MCParsedAsmOperand { } Mem; }; + X86Operand(KindTy K, SMLoc Start, SMLoc End) + : Kind(K), StartLoc(Start), EndLoc(End) {} + + /// getStartLoc - Get the location of the first token of this operand. + SMLoc getStartLoc() const { return StartLoc; } + /// getEndLoc - Get the location of the last token of this operand. + SMLoc getEndLoc() const { return EndLoc; } + StringRef getToken() const { assert(Kind == Token && "Invalid access!"); return StringRef(Tok.Data, Tok.Length); @@ -192,44 +203,40 @@ struct X86Operand : public MCParsedAsmOperand { Inst.addOperand(MCOperand::CreateReg(getMemSegReg())); } - static X86Operand CreateToken(StringRef Str) { - X86Operand Res; - Res.Kind = Token; - Res.Tok.Data = Str.data(); - Res.Tok.Length = Str.size(); + static X86Operand *CreateToken(StringRef Str, SMLoc Loc) { + X86Operand *Res = new X86Operand(Token, Loc, Loc); + Res->Tok.Data = Str.data(); + Res->Tok.Length = Str.size(); return Res; } - static X86Operand CreateReg(unsigned RegNo) { - X86Operand Res; - Res.Kind = Register; - Res.Reg.RegNo = RegNo; + static X86Operand *CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc) { + X86Operand *Res = new X86Operand(Register, StartLoc, EndLoc); + Res->Reg.RegNo = RegNo; return Res; } - static X86Operand CreateImm(const MCExpr *Val) { - X86Operand Res; - Res.Kind = Immediate; - Res.Imm.Val = Val; + static X86Operand *CreateImm(const MCExpr *Val, SMLoc StartLoc, SMLoc EndLoc){ + X86Operand *Res = new X86Operand(Immediate, StartLoc, EndLoc); + Res->Imm.Val = Val; return Res; } - static X86Operand CreateMem(unsigned SegReg, const MCExpr *Disp, - unsigned BaseReg, unsigned IndexReg, - unsigned Scale) { + static X86Operand *CreateMem(unsigned SegReg, const MCExpr *Disp, + unsigned BaseReg, unsigned IndexReg, + unsigned Scale, SMLoc StartLoc, SMLoc EndLoc) { // We should never just have a displacement, that would be an immediate. assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!"); // The scale should always be one of {1,2,4,8}. assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) && "Invalid scale!"); - X86Operand Res; - Res.Kind = Memory; - Res.Mem.SegReg = SegReg; - Res.Mem.Disp = Disp; - Res.Mem.BaseReg = BaseReg; - Res.Mem.IndexReg = IndexReg; - Res.Mem.Scale = Scale; + X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc); + Res->Mem.SegReg = SegReg; + Res->Mem.Disp = Disp; + Res->Mem.BaseReg = BaseReg; + Res->Mem.IndexReg = IndexReg; + Res->Mem.Scale = Scale; return Res; } }; @@ -237,52 +244,57 @@ struct X86Operand : public MCParsedAsmOperand { } // end anonymous namespace. -bool X86ATTAsmParser::ParseRegister(X86Operand &Op) { - const AsmToken &TokPercent = getLexer().getTok(); - (void)TokPercent; // Avoid warning when assertions are disabled. +bool X86ATTAsmParser::ParseRegister(unsigned &RegNo, + SMLoc &StartLoc, SMLoc &EndLoc) { + RegNo = 0; + const AsmToken &TokPercent = Parser.getTok(); assert(TokPercent.is(AsmToken::Percent) && "Invalid token kind!"); - getLexer().Lex(); // Eat percent token. + StartLoc = TokPercent.getLoc(); + Parser.Lex(); // Eat percent token. - const AsmToken &Tok = getLexer().getTok(); + const AsmToken &Tok = Parser.getTok(); if (Tok.isNot(AsmToken::Identifier)) return Error(Tok.getLoc(), "invalid register name"); // FIXME: Validate register for the current architecture; we have to do // validation later, so maybe there is no need for this here. - unsigned RegNo; - RegNo = MatchRegisterName(Tok.getString()); if (RegNo == 0) return Error(Tok.getLoc(), "invalid register name"); - Op = X86Operand::CreateReg(RegNo); - getLexer().Lex(); // Eat identifier token. - + EndLoc = Tok.getLoc(); + Parser.Lex(); // Eat identifier token. return false; } -bool X86ATTAsmParser::ParseOperand(X86Operand &Op) { +X86Operand *X86ATTAsmParser::ParseOperand() { switch (getLexer().getKind()) { default: - return ParseMemOperand(Op); - case AsmToken::Percent: + return ParseMemOperand(); + case AsmToken::Percent: { // FIXME: if a segment register, this could either be just the seg reg, or // the start of a memory operand. - return ParseRegister(Op); + unsigned RegNo; + SMLoc Start, End; + if (ParseRegister(RegNo, Start, End)) return 0; + return X86Operand::CreateReg(RegNo, Start, End); + } case AsmToken::Dollar: { // $42 -> immediate. - getLexer().Lex(); + SMLoc Start = Parser.getTok().getLoc(), End; + Parser.Lex(); const MCExpr *Val; - if (getParser().ParseExpression(Val)) - return true; - Op = X86Operand::CreateImm(Val); - return false; + if (getParser().ParseExpression(Val, End)) + return 0; + return X86Operand::CreateImm(Val, Start, End); } } } /// ParseMemOperand: segment: disp(basereg, indexreg, scale) -bool X86ATTAsmParser::ParseMemOperand(X86Operand &Op) { +X86Operand *X86ATTAsmParser::ParseMemOperand() { + SMLoc MemStart = Parser.getTok().getLoc(); + // FIXME: If SegReg ':' (e.g. %gs:), eat and remember. unsigned SegReg = 0; @@ -292,47 +304,47 @@ bool X86ATTAsmParser::ParseMemOperand(X86Operand &Op) { // it. const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext()); if (getLexer().isNot(AsmToken::LParen)) { - if (getParser().ParseExpression(Disp)) return true; + SMLoc ExprEnd; + if (getParser().ParseExpression(Disp, ExprEnd)) return 0; // After parsing the base expression we could either have a parenthesized // memory address or not. If not, return now. If so, eat the (. if (getLexer().isNot(AsmToken::LParen)) { // Unless we have a segment register, treat this as an immediate. - if (SegReg) - Op = X86Operand::CreateMem(SegReg, Disp, 0, 0, 1); - else - Op = X86Operand::CreateImm(Disp); - return false; + if (SegReg == 0) + return X86Operand::CreateImm(Disp, MemStart, ExprEnd); + return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd); } // Eat the '('. - getLexer().Lex(); + Parser.Lex(); } else { // Okay, we have a '('. We don't know if this is an expression or not, but // so we have to eat the ( to see beyond it. - getLexer().Lex(); // Eat the '('. + SMLoc LParenLoc = Parser.getTok().getLoc(); + Parser.Lex(); // Eat the '('. if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) { // Nothing to do here, fall into the code below with the '(' part of the // memory operand consumed. } else { + SMLoc ExprEnd; + // It must be an parenthesized expression, parse it now. - if (getParser().ParseParenExpression(Disp)) - return true; + if (getParser().ParseParenExpression(Disp, ExprEnd)) + return 0; // After parsing the base expression we could either have a parenthesized // memory address or not. If not, return now. If so, eat the (. if (getLexer().isNot(AsmToken::LParen)) { // Unless we have a segment register, treat this as an immediate. - if (SegReg) - Op = X86Operand::CreateMem(SegReg, Disp, 0, 0, 1); - else - Op = X86Operand::CreateImm(Disp); - return false; + if (SegReg == 0) + return X86Operand::CreateImm(Disp, LParenLoc, ExprEnd); + return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd); } // Eat the '('. - getLexer().Lex(); + Parser.Lex(); } } @@ -341,13 +353,12 @@ bool X86ATTAsmParser::ParseMemOperand(X86Operand &Op) { unsigned BaseReg = 0, IndexReg = 0, Scale = 1; if (getLexer().is(AsmToken::Percent)) { - if (ParseRegister(Op)) - return true; - BaseReg = Op.getReg(); + SMLoc L; + if (ParseRegister(BaseReg, L, L)) return 0; } if (getLexer().is(AsmToken::Comma)) { - getLexer().Lex(); // Eat the comma. + Parser.Lex(); // Eat the comma. // Following the comma we should have either an index register, or a scale // value. We don't support the later form, but we want to parse it @@ -356,82 +367,89 @@ bool X86ATTAsmParser::ParseMemOperand(X86Operand &Op) { // Not that even though it would be completely consistent to support syntax // like "1(%eax,,1)", the assembler doesn't. if (getLexer().is(AsmToken::Percent)) { - if (ParseRegister(Op)) - return true; - IndexReg = Op.getReg(); + SMLoc L; + if (ParseRegister(IndexReg, L, L)) return 0; if (getLexer().isNot(AsmToken::RParen)) { // Parse the scale amount: // ::= ',' [scale-expression] - if (getLexer().isNot(AsmToken::Comma)) - return true; - getLexer().Lex(); // Eat the comma. + if (getLexer().isNot(AsmToken::Comma)) { + Error(Parser.getTok().getLoc(), + "expected comma in scale expression"); + return 0; + } + Parser.Lex(); // Eat the comma. if (getLexer().isNot(AsmToken::RParen)) { - SMLoc Loc = getLexer().getTok().getLoc(); + SMLoc Loc = Parser.getTok().getLoc(); int64_t ScaleVal; if (getParser().ParseAbsoluteExpression(ScaleVal)) - return true; + return 0; // Validate the scale amount. - if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8) - return Error(Loc, "scale factor in address must be 1, 2, 4 or 8"); + if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8){ + Error(Loc, "scale factor in address must be 1, 2, 4 or 8"); + return 0; + } Scale = (unsigned)ScaleVal; } } } else if (getLexer().isNot(AsmToken::RParen)) { // Otherwise we have the unsupported form of a scale amount without an // index. - SMLoc Loc = getLexer().getTok().getLoc(); + SMLoc Loc = Parser.getTok().getLoc(); int64_t Value; if (getParser().ParseAbsoluteExpression(Value)) - return true; + return 0; - return Error(Loc, "cannot have scale factor without index register"); + Error(Loc, "cannot have scale factor without index register"); + return 0; } } // Ok, we've eaten the memory operand, verify we have a ')' and eat it too. - if (getLexer().isNot(AsmToken::RParen)) - return Error(getLexer().getTok().getLoc(), - "unexpected token in memory operand"); - getLexer().Lex(); // Eat the ')'. + if (getLexer().isNot(AsmToken::RParen)) { + Error(Parser.getTok().getLoc(), "unexpected token in memory operand"); + return 0; + } + SMLoc MemEnd = Parser.getTok().getLoc(); + Parser.Lex(); // Eat the ')'. - Op = X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale); - return false; + return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale, + MemStart, MemEnd); } bool X86ATTAsmParser:: ParseInstruction(const StringRef &Name, SMLoc NameLoc, SmallVectorImpl<MCParsedAsmOperand*> &Operands) { - Operands.push_back(new X86Operand(X86Operand::CreateToken(Name))); + Operands.push_back(X86Operand::CreateToken(Name, NameLoc)); - SMLoc Loc = getLexer().getTok().getLoc(); if (getLexer().isNot(AsmToken::EndOfStatement)) { // Parse '*' modifier. if (getLexer().is(AsmToken::Star)) { - getLexer().Lex(); // Eat the star. - Operands.push_back(new X86Operand(X86Operand::CreateToken("*"))); + SMLoc Loc = Parser.getTok().getLoc(); + Operands.push_back(X86Operand::CreateToken("*", Loc)); + Parser.Lex(); // Eat the star. } // Read the first operand. - X86Operand Op; - if (ParseOperand(Op)) + if (X86Operand *Op = ParseOperand()) + Operands.push_back(Op); + else return true; - - Operands.push_back(new X86Operand(Op)); - + while (getLexer().is(AsmToken::Comma)) { - getLexer().Lex(); // Eat the comma. + Parser.Lex(); // Eat the comma. // Parse and remember the operand. - if (ParseOperand(Op)) + if (X86Operand *Op = ParseOperand()) + Operands.push_back(Op); + else return true; - Operands.push_back(new X86Operand(Op)); } } @@ -454,7 +472,7 @@ bool X86ATTAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { if (getParser().ParseExpression(Value)) return true; - getParser().getStreamer().EmitValue(Value, Size); + getParser().getStreamer().EmitValue(Value, Size, 0 /*addrspace*/); if (getLexer().is(AsmToken::EndOfStatement)) break; @@ -462,18 +480,21 @@ bool X86ATTAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { // FIXME: Improve diagnostic. if (getLexer().isNot(AsmToken::Comma)) return Error(L, "unexpected token in directive"); - getLexer().Lex(); + Parser.Lex(); } } - getLexer().Lex(); + Parser.Lex(); return false; } +extern "C" void LLVMInitializeX86AsmLexer(); + // Force static initialization. extern "C" void LLVMInitializeX86AsmParser() { RegisterAsmParser<X86ATTAsmParser> X(TheX86_32Target); RegisterAsmParser<X86ATTAsmParser> Y(TheX86_64Target); + LLVMInitializeX86AsmLexer(); } #include "X86GenAsmMatcher.inc" |