|  | //===-- X86AsmLexer.cpp - Tokenize X86 assembly to AsmTokens --------------===// | 
|  | // | 
|  | //                     The LLVM Compiler Infrastructure | 
|  | // | 
|  | // This file is distributed under the University of Illinois Open Source | 
|  | // License. See LICENSE.TXT for details. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #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" | 
|  |  | 
|  | using namespace llvm; | 
|  |  | 
|  | 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; | 
|  | } | 
|  | return getLexer()->Lex(); | 
|  | } | 
|  |  | 
|  | AsmToken LexTokenATT(); | 
|  | AsmToken LexTokenIntel(); | 
|  | protected: | 
|  | 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), tentativeIsValid(false) { | 
|  | } | 
|  | }; | 
|  |  | 
|  | } | 
|  |  | 
|  | static unsigned MatchRegisterName(StringRef Name); | 
|  |  | 
|  | AsmToken X86AsmLexer::LexTokenATT() { | 
|  | AsmToken lexedToken = lexDefinite(); | 
|  |  | 
|  | switch (lexedToken.getKind()) { | 
|  | default: | 
|  | return lexedToken; | 
|  | case AsmToken::Error: | 
|  | SetError(Lexer->getErrLoc(), Lexer->getErr()); | 
|  | return lexedToken; | 
|  |  | 
|  | case AsmToken::Percent: { | 
|  | const AsmToken &nextToken = lexTentative(); | 
|  | if (nextToken.getKind() != AsmToken::Identifier) | 
|  | return lexedToken; | 
|  |  | 
|  |  | 
|  | if (unsigned regID = MatchRegisterName(nextToken.getString())) { | 
|  | lexDefinite(); | 
|  |  | 
|  | // FIXME: This is completely wrong when there is a space or other | 
|  | // punctuation between the % and the register name. | 
|  | StringRef regStr(lexedToken.getString().data(), | 
|  | lexedToken.getString().size() + | 
|  | nextToken.getString().size()); | 
|  |  | 
|  | return AsmToken(AsmToken::Register, regStr, | 
|  | static_cast<int64_t>(regID)); | 
|  | } | 
|  |  | 
|  | // Match register name failed.  If this is "db[0-7]", match it as an alias | 
|  | // for dr[0-7]. | 
|  | if (nextToken.getString().size() == 3 && | 
|  | nextToken.getString().startswith("db")) { | 
|  | int RegNo = -1; | 
|  | switch (nextToken.getString()[2]) { | 
|  | case '0': RegNo = X86::DR0; break; | 
|  | case '1': RegNo = X86::DR1; break; | 
|  | case '2': RegNo = X86::DR2; break; | 
|  | case '3': RegNo = X86::DR3; break; | 
|  | case '4': RegNo = X86::DR4; break; | 
|  | case '5': RegNo = X86::DR5; break; | 
|  | case '6': RegNo = X86::DR6; break; | 
|  | case '7': RegNo = X86::DR7; break; | 
|  | } | 
|  |  | 
|  | if (RegNo != -1) { | 
|  | lexDefinite(); | 
|  |  | 
|  | // FIXME: This is completely wrong when there is a space or other | 
|  | // punctuation between the % and the register name. | 
|  | StringRef regStr(lexedToken.getString().data(), | 
|  | lexedToken.getString().size() + | 
|  | nextToken.getString().size()); | 
|  | return AsmToken(AsmToken::Register, regStr, | 
|  | static_cast<int64_t>(RegNo)); | 
|  | } | 
|  | } | 
|  |  | 
|  |  | 
|  | return lexedToken; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | AsmToken X86AsmLexer::LexTokenIntel() { | 
|  | const AsmToken &lexedToken = lexDefinite(); | 
|  |  | 
|  | switch(lexedToken.getKind()) { | 
|  | default: | 
|  | return lexedToken; | 
|  | case AsmToken::Error: | 
|  | SetError(Lexer->getErrLoc(), Lexer->getErr()); | 
|  | return 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)); | 
|  | return lexedToken; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | extern "C" void LLVMInitializeX86AsmLexer() { | 
|  | RegisterAsmLexer<X86AsmLexer> X(TheX86_32Target); | 
|  | RegisterAsmLexer<X86AsmLexer> Y(TheX86_64Target); | 
|  | } | 
|  |  | 
|  | #define REGISTERS_ONLY | 
|  | #include "X86GenAsmMatcher.inc" | 
|  | #undef REGISTERS_ONLY |