diff options
Diffstat (limited to 'contrib/llvm/lib/Target/X86/AsmParser/X86AsmLexer.cpp')
-rw-r--r-- | contrib/llvm/lib/Target/X86/AsmParser/X86AsmLexer.cpp | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/contrib/llvm/lib/Target/X86/AsmParser/X86AsmLexer.cpp b/contrib/llvm/lib/Target/X86/AsmParser/X86AsmLexer.cpp new file mode 100644 index 0000000..1eaccff --- /dev/null +++ b/contrib/llvm/lib/Target/X86/AsmParser/X86AsmLexer.cpp @@ -0,0 +1,165 @@ +//===-- 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 "MCTargetDesc/X86BaseInfo.h" +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCParser/MCAsmLexer.h" +#include "llvm/MC/MCParser/MCParsedAsmOperand.h" +#include "llvm/MC/MCTargetAsmLexer.h" +#include "llvm/Support/TargetRegistry.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringExtras.h" + +using namespace llvm; + +namespace { + +class X86AsmLexer : public MCTargetAsmLexer { + 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 MCRegisterInfo &MRI, const MCAsmInfo &MAI) + : MCTargetAsmLexer(T), AsmInfo(MAI), tentativeIsValid(false) { + } +}; + +} // end anonymous namespace + +#define GET_REGISTER_MATCHER +#include "X86GenAsmMatcher.inc" + +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() { + RegisterMCAsmLexer<X86AsmLexer> X(TheX86_32Target); + RegisterMCAsmLexer<X86AsmLexer> Y(TheX86_64Target); +} |