diff options
Diffstat (limited to 'lib/Target/X86/AsmParser/X86AsmLexer.cpp')
-rw-r--r-- | lib/Target/X86/AsmParser/X86AsmLexer.cpp | 118 |
1 files changed, 111 insertions, 7 deletions
diff --git a/lib/Target/X86/AsmParser/X86AsmLexer.cpp b/lib/Target/X86/AsmParser/X86AsmLexer.cpp index 1a62044..a58f58e 100644 --- a/lib/Target/X86/AsmParser/X86AsmLexer.cpp +++ b/lib/Target/X86/AsmParser/X86AsmLexer.cpp @@ -7,8 +7,11 @@ // //===----------------------------------------------------------------------===// +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/Target/TargetAsmLexer.h" #include "llvm/Target/TargetRegistry.h" +#include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCParser/MCAsmLexer.h" #include "llvm/MC/MCParser/MCParsedAsmOperand.h" #include "X86.h" @@ -19,18 +22,119 @@ namespace { class X86AsmLexer : public TargetAsmLexer { const MCAsmInfo &AsmInfo; + + bool tentativeIsValid; + AsmToken tentativeToken; + + const AsmToken &lexTentative() { + tentativeToken = getLexer()->Lex(); + tentativeIsValid = true; + return tentativeToken; + } + + const AsmToken &lexDefinite() { + if(tentativeIsValid) { + tentativeIsValid = false; + return tentativeToken; + } + else { + return getLexer()->Lex(); + } + } + + AsmToken LexTokenATT(); + AsmToken LexTokenIntel(); protected: - AsmToken LexToken(); + AsmToken LexToken() { + if (!Lexer) { + SetError(SMLoc(), "No MCAsmLexer installed"); + return AsmToken(AsmToken::Error, "", 0); + } + + switch (AsmInfo.getAssemblerDialect()) { + default: + SetError(SMLoc(), "Unhandled dialect"); + return AsmToken(AsmToken::Error, "", 0); + case 0: + return LexTokenATT(); + case 1: + return LexTokenIntel(); + } + } public: X86AsmLexer(const Target &T, const MCAsmInfo &MAI) - : TargetAsmLexer(T), AsmInfo(MAI) { + : TargetAsmLexer(T), AsmInfo(MAI), tentativeIsValid(false) { } }; } -AsmToken X86AsmLexer::LexToken() { - return AsmToken(AsmToken::Error, "", 0); +static unsigned MatchRegisterName(StringRef Name); + +AsmToken X86AsmLexer::LexTokenATT() { + const AsmToken lexedToken = lexDefinite(); + + switch (lexedToken.getKind()) { + default: + return AsmToken(lexedToken); + case AsmToken::Error: + SetError(Lexer->getErrLoc(), Lexer->getErr()); + return AsmToken(lexedToken); + case AsmToken::Percent: + { + const AsmToken &nextToken = lexTentative(); + if (nextToken.getKind() == AsmToken::Identifier) { + unsigned regID = MatchRegisterName(nextToken.getString()); + + if (regID) { + lexDefinite(); + + StringRef regStr(lexedToken.getString().data(), + lexedToken.getString().size() + + nextToken.getString().size()); + + return AsmToken(AsmToken::Register, + regStr, + static_cast<int64_t>(regID)); + } + else { + return AsmToken(lexedToken); + } + } + else { + return AsmToken(lexedToken); + } + } + } +} + +AsmToken X86AsmLexer::LexTokenIntel() { + const AsmToken &lexedToken = lexDefinite(); + + switch(lexedToken.getKind()) { + default: + return AsmToken(lexedToken); + case AsmToken::Error: + SetError(Lexer->getErrLoc(), Lexer->getErr()); + return AsmToken(lexedToken); + case AsmToken::Identifier: + { + std::string upperCase = lexedToken.getString().str(); + std::string lowerCase = LowercaseString(upperCase); + StringRef lowerRef(lowerCase); + + unsigned regID = MatchRegisterName(lowerRef); + + if (regID) { + return AsmToken(AsmToken::Register, + lexedToken.getString(), + static_cast<int64_t>(regID)); + } + else { + return AsmToken(lexedToken); + } + } + } } extern "C" void LLVMInitializeX86AsmLexer() { @@ -38,6 +142,6 @@ extern "C" void LLVMInitializeX86AsmLexer() { RegisterAsmLexer<X86AsmLexer> Y(TheX86_64Target); } -//#define REGISTERS_ONLY -//#include "../X86GenAsmMatcher.inc" -//#undef REGISTERS_ONLY +#define REGISTERS_ONLY +#include "X86GenAsmMatcher.inc" +#undef REGISTERS_ONLY |