1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-25 04:02:41 +01:00
llvm-mirror/lib/Target/X86/AsmParser/X86AsmLexer.cpp
Chris Lattner 45a204be76 have AsmMatcherEmitter.cpp produce the hunk of code that gets included
into the middle of the class, and rework how the different sections of
the generated file are conditionally included for simplicity.

llvm-svn: 113163
2010-09-06 19:11:01 +00:00

166 lines
4.6 KiB
C++

//===-- 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) {
}
};
} // 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() {
RegisterAsmLexer<X86AsmLexer> X(TheX86_32Target);
RegisterAsmLexer<X86AsmLexer> Y(TheX86_64Target);
}