X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FARM%2FAsmParser%2FARMAsmParser.cpp;h=4b083244b2413eea9f6b7be09f10f54e38fe8e4c;hb=38e59891ee4417a9be2f8146ce0ba3269e38ac21;hp=9288384508c626b7456d79faac61cc8153a66030;hpb=f007e853e26845cd6866b52d646455fc69f4e0af;p=oota-llvm.git diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 9288384508c..4b083244b24 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -8,18 +8,19 @@ //===----------------------------------------------------------------------===// #include "ARM.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/Twine.h" -#include "llvm/MC/MCAsmLexer.h" -#include "llvm/MC/MCAsmParser.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/MC/MCStreamer.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" -#include "llvm/Support/Compiler.h" -#include "llvm/Support/SourceMgr.h" #include "llvm/Target/TargetRegistry.h" #include "llvm/Target/TargetAsmParser.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/SourceMgr.h" +#include "llvm/ADT/OwningPtr.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/Twine.h" using namespace llvm; namespace { @@ -46,11 +47,11 @@ private: bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); } - bool MaybeParseRegister(ARMOperand &Op, bool ParseWriteBack); + bool MaybeParseRegister(OwningPtr &Op, bool ParseWriteBack); - bool ParseRegisterList(ARMOperand &Op); + bool ParseRegisterList(OwningPtr &Op); - bool ParseMemory(ARMOperand &Op); + bool ParseMemory(OwningPtr &Op); bool ParseMemoryOffsetReg(bool &Negative, bool &OffsetRegShifted, @@ -58,11 +59,12 @@ private: const MCExpr *&ShiftAmount, const MCExpr *&Offset, bool &OffsetIsReg, - int &OffsetRegNum); + int &OffsetRegNum, + SMLoc &E); - bool ParseShift(enum ShiftType &St, const MCExpr *&ShiftAmount); + bool ParseShift(enum ShiftType &St, const MCExpr *&ShiftAmount, SMLoc &E); - bool ParseOperand(ARMOperand &Op); + bool ParseOperand(OwningPtr &Op); bool ParseDirectiveWord(unsigned Size, SMLoc L); @@ -79,14 +81,14 @@ private: /// @name Auto-generated Match Functions /// { - bool MatchInstruction(SmallVectorImpl &Operands, + bool MatchInstruction(const SmallVectorImpl &Operands, MCInst &Inst); /// MatchRegisterName - Match the given string to a register name and return /// its register number, or -1 if there is no match. To allow return values /// to be used directly in register lists, arm registers have values between /// 0 and 15. - int MatchRegisterName(const StringRef &Name); + int MatchRegisterName(StringRef Name); /// } @@ -95,8 +97,8 @@ public: ARMAsmParser(const Target &T, MCAsmParser &_Parser) : TargetAsmParser(T), Parser(_Parser) {} - virtual bool ParseInstruction(const StringRef &Name, SMLoc NameLoc, - MCInst &Inst); + virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc, + SmallVectorImpl &Operands); virtual bool ParseDirective(AsmToken DirectiveID); }; @@ -104,13 +106,17 @@ public: /// ARMOperand - Instances of this class represent a parsed ARM machine /// instruction. struct ARMOperand : public MCParsedAsmOperand { - enum { +private: + ARMOperand() {} +public: + enum KindTy { Token, Register, Immediate, Memory } Kind; + SMLoc StartLoc, EndLoc; union { struct { @@ -126,7 +132,7 @@ struct ARMOperand : public MCParsedAsmOperand { struct { const MCExpr *Val; } Imm; - + // This is for all forms of ARM address expressions struct { unsigned BaseRegNum; @@ -144,6 +150,34 @@ struct ARMOperand : public MCParsedAsmOperand { } Mem; }; + + ARMOperand(KindTy K, SMLoc S, SMLoc E) + : Kind(K), StartLoc(S), EndLoc(E) {} + + ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() { + Kind = o.Kind; + StartLoc = o.StartLoc; + EndLoc = o.EndLoc; + switch (Kind) { + case Token: + Tok = o.Tok; + break; + case Register: + Reg = o.Reg; + break; + case Immediate: + Imm = o.Imm; + break; + case Memory: + Mem = o.Mem; + break; + } + } + + /// 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!"); @@ -169,48 +203,60 @@ struct ARMOperand : public MCParsedAsmOperand { Inst.addOperand(MCOperand::CreateReg(getReg())); } - static ARMOperand CreateToken(StringRef Str) { - ARMOperand Res; - Res.Kind = Token; - Res.Tok.Data = Str.data(); - Res.Tok.Length = Str.size(); - return Res; + static void CreateToken(OwningPtr &Op, StringRef Str, + SMLoc S) { + Op.reset(new ARMOperand); + Op->Kind = Token; + Op->Tok.Data = Str.data(); + Op->Tok.Length = Str.size(); + Op->StartLoc = S; + Op->EndLoc = S; } - static ARMOperand CreateReg(unsigned RegNum, bool Writeback) { - ARMOperand Res; - Res.Kind = Register; - Res.Reg.RegNum = RegNum; - Res.Reg.Writeback = Writeback; - return Res; + static void CreateReg(OwningPtr &Op, unsigned RegNum, + bool Writeback, SMLoc S, SMLoc E) { + Op.reset(new ARMOperand); + Op->Kind = Register; + Op->Reg.RegNum = RegNum; + Op->Reg.Writeback = Writeback; + + Op->StartLoc = S; + Op->EndLoc = E; } - static ARMOperand CreateImm(const MCExpr *Val) { - ARMOperand Res; - Res.Kind = Immediate; - Res.Imm.Val = Val; - return Res; + static void CreateImm(OwningPtr &Op, const MCExpr *Val, + SMLoc S, SMLoc E) { + Op.reset(new ARMOperand); + Op->Kind = Immediate; + Op->Imm.Val = Val; + + Op->StartLoc = S; + Op->EndLoc = E; } - static ARMOperand CreateMem(unsigned BaseRegNum, bool OffsetIsReg, - const MCExpr *Offset, unsigned OffsetRegNum, - bool OffsetRegShifted, enum ShiftType ShiftType, - const MCExpr *ShiftAmount, bool Preindexed, - bool Postindexed, bool Negative, bool Writeback) { - ARMOperand Res; - Res.Kind = Memory; - Res.Mem.BaseRegNum = BaseRegNum; - Res.Mem.OffsetIsReg = OffsetIsReg; - Res.Mem.Offset = Offset; - Res.Mem.OffsetRegNum = OffsetRegNum; - Res.Mem.OffsetRegShifted = OffsetRegShifted; - Res.Mem.ShiftType = ShiftType; - Res.Mem.ShiftAmount = ShiftAmount; - Res.Mem.Preindexed = Preindexed; - Res.Mem.Postindexed = Postindexed; - Res.Mem.Negative = Negative; - Res.Mem.Writeback = Writeback; - return Res; + static void CreateMem(OwningPtr &Op, + unsigned BaseRegNum, bool OffsetIsReg, + const MCExpr *Offset, unsigned OffsetRegNum, + bool OffsetRegShifted, enum ShiftType ShiftType, + const MCExpr *ShiftAmount, bool Preindexed, + bool Postindexed, bool Negative, bool Writeback, + SMLoc S, SMLoc E) { + Op.reset(new ARMOperand); + Op->Kind = Memory; + Op->Mem.BaseRegNum = BaseRegNum; + Op->Mem.OffsetIsReg = OffsetIsReg; + Op->Mem.Offset = Offset; + Op->Mem.OffsetRegNum = OffsetRegNum; + Op->Mem.OffsetRegShifted = OffsetRegShifted; + Op->Mem.ShiftType = ShiftType; + Op->Mem.ShiftAmount = ShiftAmount; + Op->Mem.Preindexed = Preindexed; + Op->Mem.Postindexed = Postindexed; + Op->Mem.Negative = Negative; + Op->Mem.Writeback = Writeback; + + Op->StartLoc = S; + Op->EndLoc = E; } }; @@ -221,8 +267,10 @@ struct ARMOperand : public MCParsedAsmOperand { /// and false is returned. Else true is returned and no token is eaten. /// TODO this is likely to change to allow different register types and or to /// parse for a specific register type. -bool ARMAsmParser::MaybeParseRegister(ARMOperand &Op, bool ParseWriteBack) { - const AsmToken &Tok = getLexer().getTok(); +bool ARMAsmParser::MaybeParseRegister + (OwningPtr &Op, bool ParseWriteBack) { + SMLoc S, E; + const AsmToken &Tok = Parser.getTok(); assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); // FIXME: Validate register for the current architecture; we have to do @@ -232,45 +280,53 @@ bool ARMAsmParser::MaybeParseRegister(ARMOperand &Op, bool ParseWriteBack) { RegNum = MatchRegisterName(Tok.getString()); if (RegNum == -1) return true; - getLexer().Lex(); // Eat identifier token. + + S = Tok.getLoc(); + + Parser.Lex(); // Eat identifier token. + + E = Parser.getTok().getLoc(); bool Writeback = false; if (ParseWriteBack) { - const AsmToken &ExclaimTok = getLexer().getTok(); + const AsmToken &ExclaimTok = Parser.getTok(); if (ExclaimTok.is(AsmToken::Exclaim)) { + E = ExclaimTok.getLoc(); Writeback = true; - getLexer().Lex(); // Eat exclaim token + Parser.Lex(); // Eat exclaim token } } - Op = ARMOperand::CreateReg(RegNum, Writeback); + ARMOperand::CreateReg(Op, RegNum, Writeback, S, E); return false; } /// Parse a register list, return false if successful else return true or an /// error. The first token must be a '{' when called. -bool ARMAsmParser::ParseRegisterList(ARMOperand &Op) { - assert(getLexer().getTok().is(AsmToken::LCurly) && +bool ARMAsmParser::ParseRegisterList(OwningPtr &Op) { + SMLoc S, E; + assert(Parser.getTok().is(AsmToken::LCurly) && "Token is not an Left Curly Brace"); - getLexer().Lex(); // Eat left curly brace token. + S = Parser.getTok().getLoc(); + Parser.Lex(); // Eat left curly brace token. - const AsmToken &RegTok = getLexer().getTok(); + const AsmToken &RegTok = Parser.getTok(); SMLoc RegLoc = RegTok.getLoc(); if (RegTok.isNot(AsmToken::Identifier)) return Error(RegLoc, "register expected"); int RegNum = MatchRegisterName(RegTok.getString()); if (RegNum == -1) return Error(RegLoc, "register expected"); - getLexer().Lex(); // Eat identifier token. + Parser.Lex(); // Eat identifier token. unsigned RegList = 1 << RegNum; int HighRegNum = RegNum; // TODO ranges like "{Rn-Rm}" - while (getLexer().getTok().is(AsmToken::Comma)) { - getLexer().Lex(); // Eat comma token. + while (Parser.getTok().is(AsmToken::Comma)) { + Parser.Lex(); // Eat comma token. - const AsmToken &RegTok = getLexer().getTok(); + const AsmToken &RegTok = Parser.getTok(); SMLoc RegLoc = RegTok.getLoc(); if (RegTok.isNot(AsmToken::Identifier)) return Error(RegLoc, "register expected"); @@ -285,12 +341,13 @@ bool ARMAsmParser::ParseRegisterList(ARMOperand &Op) { RegList |= 1 << RegNum; HighRegNum = RegNum; - getLexer().Lex(); // Eat identifier token. + Parser.Lex(); // Eat identifier token. } - const AsmToken &RCurlyTok = getLexer().getTok(); + const AsmToken &RCurlyTok = Parser.getTok(); if (RCurlyTok.isNot(AsmToken::RCurly)) return Error(RCurlyTok.getLoc(), "'}' expected"); - getLexer().Lex(); // Eat left curly brace token. + E = RCurlyTok.getLoc(); + Parser.Lex(); // Eat left curly brace token. return false; } @@ -299,17 +356,19 @@ bool ARMAsmParser::ParseRegisterList(ARMOperand &Op) { /// or an error. The first token must be a '[' when called. /// TODO Only preindexing and postindexing addressing are started, unindexed /// with option, etc are still to do. -bool ARMAsmParser::ParseMemory(ARMOperand &Op) { - assert(getLexer().getTok().is(AsmToken::LBrac) && +bool ARMAsmParser::ParseMemory(OwningPtr &Op) { + SMLoc S, E; + assert(Parser.getTok().is(AsmToken::LBrac) && "Token is not an Left Bracket"); - getLexer().Lex(); // Eat left bracket token. + S = Parser.getTok().getLoc(); + Parser.Lex(); // Eat left bracket token. - const AsmToken &BaseRegTok = getLexer().getTok(); + const AsmToken &BaseRegTok = Parser.getTok(); if (BaseRegTok.isNot(AsmToken::Identifier)) return Error(BaseRegTok.getLoc(), "register expected"); if (MaybeParseRegister(Op, false)) return Error(BaseRegTok.getLoc(), "register expected"); - int BaseRegNum = Op.getReg(); + int BaseRegNum = Op->getReg(); bool Preindexed = false; bool Postindexed = false; @@ -319,31 +378,33 @@ bool ARMAsmParser::ParseMemory(ARMOperand &Op) { // First look for preindexed address forms, that is after the "[Rn" we now // have to see if the next token is a comma. - const AsmToken &Tok = getLexer().getTok(); + const AsmToken &Tok = Parser.getTok(); if (Tok.is(AsmToken::Comma)) { Preindexed = true; - getLexer().Lex(); // Eat comma token. + Parser.Lex(); // Eat comma token. int OffsetRegNum; bool OffsetRegShifted; enum ShiftType ShiftType; const MCExpr *ShiftAmount; const MCExpr *Offset; if(ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, ShiftAmount, - Offset, OffsetIsReg, OffsetRegNum)) + Offset, OffsetIsReg, OffsetRegNum, E)) return true; - const AsmToken &RBracTok = getLexer().getTok(); + const AsmToken &RBracTok = Parser.getTok(); if (RBracTok.isNot(AsmToken::RBrac)) return Error(RBracTok.getLoc(), "']' expected"); - getLexer().Lex(); // Eat right bracket token. + E = RBracTok.getLoc(); + Parser.Lex(); // Eat right bracket token. - const AsmToken &ExclaimTok = getLexer().getTok(); + const AsmToken &ExclaimTok = Parser.getTok(); if (ExclaimTok.is(AsmToken::Exclaim)) { + E = ExclaimTok.getLoc(); Writeback = true; - getLexer().Lex(); // Eat exclaim token + Parser.Lex(); // Eat exclaim token } - Op = ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset, OffsetRegNum, - OffsetRegShifted, ShiftType, ShiftAmount, - Preindexed, Postindexed, Negative, Writeback); + ARMOperand::CreateMem(Op, BaseRegNum, OffsetIsReg, Offset, OffsetRegNum, + OffsetRegShifted, ShiftType, ShiftAmount, + Preindexed, Postindexed, Negative, Writeback, S, E); return false; } // The "[Rn" we have so far was not followed by a comma. @@ -352,7 +413,8 @@ bool ARMAsmParser::ParseMemory(ARMOperand &Op) { // the "[Rn". Postindexed = true; Writeback = true; - getLexer().Lex(); // Eat right bracket token. + E = Tok.getLoc(); + Parser.Lex(); // Eat right bracket token. int OffsetRegNum = 0; bool OffsetRegShifted = false; @@ -360,19 +422,20 @@ bool ARMAsmParser::ParseMemory(ARMOperand &Op) { const MCExpr *ShiftAmount; const MCExpr *Offset; - const AsmToken &NextTok = getLexer().getTok(); + const AsmToken &NextTok = Parser.getTok(); if (NextTok.isNot(AsmToken::EndOfStatement)) { if (NextTok.isNot(AsmToken::Comma)) - return Error(NextTok.getLoc(), "',' expected"); - getLexer().Lex(); // Eat comma token. + return Error(NextTok.getLoc(), "',' expected"); + Parser.Lex(); // Eat comma token. if(ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, - ShiftAmount, Offset, OffsetIsReg, OffsetRegNum)) + ShiftAmount, Offset, OffsetIsReg, OffsetRegNum, + E)) return true; } - Op = ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset, OffsetRegNum, - OffsetRegShifted, ShiftType, ShiftAmount, - Preindexed, Postindexed, Negative, Writeback); + ARMOperand::CreateMem(Op, BaseRegNum, OffsetIsReg, Offset, OffsetRegNum, + OffsetRegShifted, ShiftType, ShiftAmount, + Preindexed, Postindexed, Negative, Writeback, S, E); return false; } @@ -387,53 +450,59 @@ bool ARMAsmParser::ParseMemory(ARMOperand &Op) { /// #offset /// we return false on success or an error otherwise. bool ARMAsmParser::ParseMemoryOffsetReg(bool &Negative, - bool &OffsetRegShifted, + bool &OffsetRegShifted, enum ShiftType &ShiftType, const MCExpr *&ShiftAmount, const MCExpr *&Offset, bool &OffsetIsReg, - int &OffsetRegNum) { - ARMOperand Op; + int &OffsetRegNum, + SMLoc &E) { + OwningPtr Op; Negative = false; OffsetRegShifted = false; OffsetIsReg = false; OffsetRegNum = -1; - const AsmToken &NextTok = getLexer().getTok(); + const AsmToken &NextTok = Parser.getTok(); + E = NextTok.getLoc(); if (NextTok.is(AsmToken::Plus)) - getLexer().Lex(); // Eat plus token. + Parser.Lex(); // Eat plus token. else if (NextTok.is(AsmToken::Minus)) { Negative = true; - getLexer().Lex(); // Eat minus token + Parser.Lex(); // Eat minus token } // See if there is a register following the "[Rn," or "[Rn]," we have so far. - const AsmToken &OffsetRegTok = getLexer().getTok(); + const AsmToken &OffsetRegTok = Parser.getTok(); if (OffsetRegTok.is(AsmToken::Identifier)) { OffsetIsReg = !MaybeParseRegister(Op, false); - if (OffsetIsReg) - OffsetRegNum = Op.getReg(); + if (OffsetIsReg) { + E = Op->getEndLoc(); + OffsetRegNum = Op->getReg(); + } } // If we parsed a register as the offset then their can be a shift after that if (OffsetRegNum != -1) { // Look for a comma then a shift - const AsmToken &Tok = getLexer().getTok(); + const AsmToken &Tok = Parser.getTok(); if (Tok.is(AsmToken::Comma)) { - getLexer().Lex(); // Eat comma token. + Parser.Lex(); // Eat comma token. - const AsmToken &Tok = getLexer().getTok(); - if (ParseShift(ShiftType, ShiftAmount)) - return Error(Tok.getLoc(), "shift expected"); + const AsmToken &Tok = Parser.getTok(); + if (ParseShift(ShiftType, ShiftAmount, E)) + return Error(Tok.getLoc(), "shift expected"); OffsetRegShifted = true; } } else { // the "[Rn," or "[Rn,]" we have so far was not followed by "Rm" // Look for #offset following the "[Rn," or "[Rn]," - const AsmToken &HashTok = getLexer().getTok(); + const AsmToken &HashTok = Parser.getTok(); if (HashTok.isNot(AsmToken::Hash)) return Error(HashTok.getLoc(), "'#' expected"); - getLexer().Lex(); // Eat hash token. + + Parser.Lex(); // Eat hash token. if (getParser().ParseExpression(Offset)) return true; + E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); } return false; } @@ -442,11 +511,13 @@ bool ARMAsmParser::ParseMemoryOffsetReg(bool &Negative, /// ( lsl | lsr | asr | ror ) , # shift_amount /// rrx /// and returns true if it parses a shift otherwise it returns false. -bool ARMAsmParser::ParseShift(ShiftType &St, const MCExpr *&ShiftAmount) { - const AsmToken &Tok = getLexer().getTok(); +bool ARMAsmParser::ParseShift(ShiftType &St, + const MCExpr *&ShiftAmount, + SMLoc &E) { + const AsmToken &Tok = Parser.getTok(); if (Tok.isNot(AsmToken::Identifier)) return true; - const StringRef &ShiftName = Tok.getString(); + StringRef ShiftName = Tok.getString(); if (ShiftName == "lsl" || ShiftName == "LSL") St = Lsl; else if (ShiftName == "lsr" || ShiftName == "LSR") @@ -459,17 +530,17 @@ bool ARMAsmParser::ParseShift(ShiftType &St, const MCExpr *&ShiftAmount) { St = Rrx; else return true; - getLexer().Lex(); // Eat shift type token. + Parser.Lex(); // Eat shift type token. // Rrx stands alone. if (St == Rrx) return false; // Otherwise, there must be a '#' and a shift amount. - const AsmToken &HashTok = getLexer().getTok(); + const AsmToken &HashTok = Parser.getTok(); if (HashTok.isNot(AsmToken::Hash)) return Error(HashTok.getLoc(), "'#' expected"); - getLexer().Lex(); // Eat hash token. + Parser.Lex(); // Eat hash token. if (getParser().ParseExpression(ShiftAmount)) return true; @@ -478,7 +549,7 @@ bool ARMAsmParser::ParseShift(ShiftType &St, const MCExpr *&ShiftAmount) { } /// A hack to allow some testing, to be replaced by a real table gen version. -int ARMAsmParser::MatchRegisterName(const StringRef &Name) { +int ARMAsmParser::MatchRegisterName(StringRef Name) { if (Name == "r0" || Name == "R0") return 0; else if (Name == "r1" || Name == "R1") @@ -517,11 +588,12 @@ int ARMAsmParser::MatchRegisterName(const StringRef &Name) { } /// A hack to allow some testing, to be replaced by a real table gen version. -bool ARMAsmParser::MatchInstruction(SmallVectorImpl &Operands, - MCInst &Inst) { - struct ARMOperand Op0 = Operands[0]; +bool ARMAsmParser:: +MatchInstruction(const SmallVectorImpl &Operands, + MCInst &Inst) { + ARMOperand &Op0 = *(ARMOperand*)Operands[0]; assert(Op0.Kind == ARMOperand::Token && "First operand not a Token"); - const StringRef &Mnemonic = Op0.getToken(); + StringRef Mnemonic = Op0.getToken(); if (Mnemonic == "add" || Mnemonic == "stmfd" || Mnemonic == "str" || @@ -549,7 +621,9 @@ bool ARMAsmParser::MatchInstruction(SmallVectorImpl &Operands, /// Parse a arm instruction operand. For now this parses the operand regardless /// of the mnemonic. -bool ARMAsmParser::ParseOperand(ARMOperand &Op) { +bool ARMAsmParser::ParseOperand(OwningPtr &Op) { + SMLoc S, E; + switch (getLexer().getKind()) { case AsmToken::Identifier: if (!MaybeParseRegister(Op, true)) @@ -557,9 +631,11 @@ bool ARMAsmParser::ParseOperand(ARMOperand &Op) { // This was not a register so parse other operands that start with an // identifier (like labels) as expressions and create them as immediates. const MCExpr *IdVal; + S = Parser.getTok().getLoc(); if (getParser().ParseExpression(IdVal)) return true; - Op = ARMOperand::CreateImm(IdVal); + E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); + ARMOperand::CreateImm(Op, IdVal, S, E); return false; case AsmToken::LBrac: return ParseMemory(Op); @@ -568,46 +644,43 @@ bool ARMAsmParser::ParseOperand(ARMOperand &Op) { case AsmToken::Hash: // #42 -> immediate. // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate - getLexer().Lex(); + S = Parser.getTok().getLoc(); + Parser.Lex(); const MCExpr *ImmVal; if (getParser().ParseExpression(ImmVal)) return true; - Op = ARMOperand::CreateImm(ImmVal); + E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); + ARMOperand::CreateImm(Op, ImmVal, S, E); return false; default: - return Error(getLexer().getTok().getLoc(), "unexpected token in operand"); + return Error(Parser.getTok().getLoc(), "unexpected token in operand"); } } /// Parse an arm instruction mnemonic followed by its operands. -bool ARMAsmParser::ParseInstruction(const StringRef &Name, SMLoc NameLoc, - MCInst &Inst) { - SmallVector Operands; - - Operands.push_back(ARMOperand::CreateToken(Name)); +bool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc, + SmallVectorImpl &Operands) { + OwningPtr Op; + ARMOperand::CreateToken(Op, Name, NameLoc); + + Operands.push_back(Op.take()); - SMLoc Loc = getLexer().getTok().getLoc(); if (getLexer().isNot(AsmToken::EndOfStatement)) { // Read the first operand. - Operands.push_back(ARMOperand()); - if (ParseOperand(Operands.back())) - return true; + OwningPtr Op; + if (ParseOperand(Op)) return true; + Operands.push_back(Op.take()); while (getLexer().is(AsmToken::Comma)) { - getLexer().Lex(); // Eat the comma. + Parser.Lex(); // Eat the comma. // Parse and remember the operand. - Operands.push_back(ARMOperand()); - if (ParseOperand(Operands.back())) - return true; + if (ParseOperand(Op)) return true; + Operands.push_back(Op.take()); } } - if (!MatchInstruction(Operands, Inst)) - return false; - - Error(Loc, "ARMAsmParser::ParseInstruction only partly implemented"); - return true; + return false; } /// ParseDirective parses the arm specific directives @@ -635,7 +708,7 @@ bool ARMAsmParser::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; @@ -643,11 +716,11 @@ bool ARMAsmParser::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; } @@ -656,7 +729,7 @@ bool ARMAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { bool ARMAsmParser::ParseDirectiveThumb(SMLoc L) { if (getLexer().isNot(AsmToken::EndOfStatement)) return Error(L, "unexpected token in directive"); - getLexer().Lex(); + Parser.Lex(); // TODO: set thumb mode // TODO: tell the MC streamer the mode @@ -667,15 +740,15 @@ bool ARMAsmParser::ParseDirectiveThumb(SMLoc L) { /// ParseDirectiveThumbFunc /// ::= .thumbfunc symbol_name bool ARMAsmParser::ParseDirectiveThumbFunc(SMLoc L) { - const AsmToken &Tok = getLexer().getTok(); + const AsmToken &Tok = Parser.getTok(); if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String)) return Error(L, "unexpected token in .syntax directive"); - StringRef ATTRIBUTE_UNUSED SymbolName = getLexer().getTok().getIdentifier(); - getLexer().Lex(); // Consume the identifier token. + StringRef ATTRIBUTE_UNUSED SymbolName = Parser.getTok().getIdentifier(); + Parser.Lex(); // Consume the identifier token. if (getLexer().isNot(AsmToken::EndOfStatement)) return Error(L, "unexpected token in directive"); - getLexer().Lex(); + Parser.Lex(); // TODO: mark symbol as a thumb symbol // getParser().getStreamer().Emit???(); @@ -685,25 +758,20 @@ bool ARMAsmParser::ParseDirectiveThumbFunc(SMLoc L) { /// ParseDirectiveSyntax /// ::= .syntax unified | divided bool ARMAsmParser::ParseDirectiveSyntax(SMLoc L) { - const AsmToken &Tok = getLexer().getTok(); + const AsmToken &Tok = Parser.getTok(); if (Tok.isNot(AsmToken::Identifier)) return Error(L, "unexpected token in .syntax directive"); - const StringRef &Mode = Tok.getString(); - bool unified_syntax; - if (Mode == "unified" || Mode == "UNIFIED") { - getLexer().Lex(); - unified_syntax = true; - } - else if (Mode == "divided" || Mode == "DIVIDED") { - getLexer().Lex(); - unified_syntax = false; - } + StringRef Mode = Tok.getString(); + if (Mode == "unified" || Mode == "UNIFIED") + Parser.Lex(); + else if (Mode == "divided" || Mode == "DIVIDED") + Parser.Lex(); else return Error(L, "unrecognized syntax mode in .syntax directive"); if (getLexer().isNot(AsmToken::EndOfStatement)) - return Error(getLexer().getTok().getLoc(), "unexpected token in directive"); - getLexer().Lex(); + return Error(Parser.getTok().getLoc(), "unexpected token in directive"); + Parser.Lex(); // TODO tell the MC streamer the mode // getParser().getStreamer().Emit???(); @@ -713,33 +781,31 @@ bool ARMAsmParser::ParseDirectiveSyntax(SMLoc L) { /// ParseDirectiveCode /// ::= .code 16 | 32 bool ARMAsmParser::ParseDirectiveCode(SMLoc L) { - const AsmToken &Tok = getLexer().getTok(); + const AsmToken &Tok = Parser.getTok(); if (Tok.isNot(AsmToken::Integer)) return Error(L, "unexpected token in .code directive"); - int64_t Val = getLexer().getTok().getIntVal(); - bool thumb_mode; - if (Val == 16) { - getLexer().Lex(); - thumb_mode = true; - } - else if (Val == 32) { - getLexer().Lex(); - thumb_mode = false; - } + int64_t Val = Parser.getTok().getIntVal(); + if (Val == 16) + Parser.Lex(); + else if (Val == 32) + Parser.Lex(); else return Error(L, "invalid operand to .code directive"); if (getLexer().isNot(AsmToken::EndOfStatement)) - return Error(getLexer().getTok().getLoc(), "unexpected token in directive"); - getLexer().Lex(); + return Error(Parser.getTok().getLoc(), "unexpected token in directive"); + Parser.Lex(); // TODO tell the MC streamer the mode // getParser().getStreamer().Emit???(); return false; } +extern "C" void LLVMInitializeARMAsmLexer(); + /// Force static initialization. extern "C" void LLVMInitializeARMAsmParser() { RegisterAsmParser X(TheARMTarget); RegisterAsmParser Y(TheThumbTarget); + LLVMInitializeARMAsmLexer(); }