X86AsmLexer.cpp revision 94b9550a32d189704a8eae55505edf62662c0534
1e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan//===-- X86AsmLexer.cpp - Tokenize X86 assembly to AsmTokens --------------===// 2e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan// 3e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan// The LLVM Compiler Infrastructure 4e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan// 5e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan// This file is distributed under the University of Illinois Open Source 6e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan// License. See LICENSE.TXT for details. 7e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan// 8e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan//===----------------------------------------------------------------------===// 9e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan 1094b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "MCTargetDesc/X86BaseInfo.h" 11436c48485c365b399a908944ebbf4f761a4f9f6aSean Callanan#include "llvm/MC/MCAsmInfo.h" 12e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan#include "llvm/MC/MCParser/MCAsmLexer.h" 13e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan#include "llvm/MC/MCParser/MCParsedAsmOperand.h" 1494b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/MC/MCTargetAsmLexer.h" 15a7cfc08ebe737062917b442830eb5321b0f79e89Evan Cheng#include "llvm/Target/TargetRegistry.h" 16a7cfc08ebe737062917b442830eb5321b0f79e89Evan Cheng#include "llvm/ADT/SmallVector.h" 17a7cfc08ebe737062917b442830eb5321b0f79e89Evan Cheng#include "llvm/ADT/StringExtras.h" 18e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan 19e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callananusing namespace llvm; 20e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan 21e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanannamespace { 22e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan 2394b9550a32d189704a8eae55505edf62662c0534Evan Chengclass X86AsmLexer : public MCTargetAsmLexer { 24e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan const MCAsmInfo &AsmInfo; 25cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan 26cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan bool tentativeIsValid; 27cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan AsmToken tentativeToken; 28cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan 29cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan const AsmToken &lexTentative() { 30894c1af05fb3f0d8e2ee6565816fa220b260ed9dSean Callanan tentativeToken = getLexer()->Lex(); 31cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan tentativeIsValid = true; 32cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan return tentativeToken; 33cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan } 34cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan 35cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan const AsmToken &lexDefinite() { 36adabe1a92cf594fc4015f83024bc06b8687f09e3Chris Lattner if (tentativeIsValid) { 37cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan tentativeIsValid = false; 38cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan return tentativeToken; 39cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan } 40adabe1a92cf594fc4015f83024bc06b8687f09e3Chris Lattner return getLexer()->Lex(); 41cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan } 42436c48485c365b399a908944ebbf4f761a4f9f6aSean Callanan 43436c48485c365b399a908944ebbf4f761a4f9f6aSean Callanan AsmToken LexTokenATT(); 44436c48485c365b399a908944ebbf4f761a4f9f6aSean Callanan AsmToken LexTokenIntel(); 45e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callananprotected: 46436c48485c365b399a908944ebbf4f761a4f9f6aSean Callanan AsmToken LexToken() { 47cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan if (!Lexer) { 48cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan SetError(SMLoc(), "No MCAsmLexer installed"); 49cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan return AsmToken(AsmToken::Error, "", 0); 50cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan } 51cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan 52436c48485c365b399a908944ebbf4f761a4f9f6aSean Callanan switch (AsmInfo.getAssemblerDialect()) { 53436c48485c365b399a908944ebbf4f761a4f9f6aSean Callanan default: 54436c48485c365b399a908944ebbf4f761a4f9f6aSean Callanan SetError(SMLoc(), "Unhandled dialect"); 55436c48485c365b399a908944ebbf4f761a4f9f6aSean Callanan return AsmToken(AsmToken::Error, "", 0); 56436c48485c365b399a908944ebbf4f761a4f9f6aSean Callanan case 0: 57436c48485c365b399a908944ebbf4f761a4f9f6aSean Callanan return LexTokenATT(); 58436c48485c365b399a908944ebbf4f761a4f9f6aSean Callanan case 1: 59436c48485c365b399a908944ebbf4f761a4f9f6aSean Callanan return LexTokenIntel(); 60436c48485c365b399a908944ebbf4f761a4f9f6aSean Callanan } 61436c48485c365b399a908944ebbf4f761a4f9f6aSean Callanan } 62e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callananpublic: 631b0fc9b4182d6bd0703cdfb3b0b91d1e093c946cEvan Cheng X86AsmLexer(const Target &T, const MCRegisterInfo &MRI, const MCAsmInfo &MAI) 6494b9550a32d189704a8eae55505edf62662c0534Evan Cheng : MCTargetAsmLexer(T), AsmInfo(MAI), tentativeIsValid(false) { 65e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan } 66e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan}; 67e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan 680692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner} // end anonymous namespace 69e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan 700692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER 710692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "X86GenAsmMatcher.inc" 72cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan 73436c48485c365b399a908944ebbf4f761a4f9f6aSean CallananAsmToken X86AsmLexer::LexTokenATT() { 74adabe1a92cf594fc4015f83024bc06b8687f09e3Chris Lattner AsmToken lexedToken = lexDefinite(); 75cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan 76cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan switch (lexedToken.getKind()) { 77cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan default: 78adabe1a92cf594fc4015f83024bc06b8687f09e3Chris Lattner return lexedToken; 79cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan case AsmToken::Error: 80cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan SetError(Lexer->getErrLoc(), Lexer->getErr()); 81adabe1a92cf594fc4015f83024bc06b8687f09e3Chris Lattner return lexedToken; 82adabe1a92cf594fc4015f83024bc06b8687f09e3Chris Lattner 83adabe1a92cf594fc4015f83024bc06b8687f09e3Chris Lattner case AsmToken::Percent: { 84cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan const AsmToken &nextToken = lexTentative(); 8502758a44e41564aafa0e50843aaedafe6b3ed7b3Chris Lattner if (nextToken.getKind() != AsmToken::Identifier) 86adabe1a92cf594fc4015f83024bc06b8687f09e3Chris Lattner return lexedToken; 8702758a44e41564aafa0e50843aaedafe6b3ed7b3Chris Lattner 88cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan 8902758a44e41564aafa0e50843aaedafe6b3ed7b3Chris Lattner if (unsigned regID = MatchRegisterName(nextToken.getString())) { 9002758a44e41564aafa0e50843aaedafe6b3ed7b3Chris Lattner lexDefinite(); 91cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan 92645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner // FIXME: This is completely wrong when there is a space or other 93645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner // punctuation between the % and the register name. 9402758a44e41564aafa0e50843aaedafe6b3ed7b3Chris Lattner StringRef regStr(lexedToken.getString().data(), 9502758a44e41564aafa0e50843aaedafe6b3ed7b3Chris Lattner lexedToken.getString().size() + 9602758a44e41564aafa0e50843aaedafe6b3ed7b3Chris Lattner nextToken.getString().size()); 9702758a44e41564aafa0e50843aaedafe6b3ed7b3Chris Lattner 98adabe1a92cf594fc4015f83024bc06b8687f09e3Chris Lattner return AsmToken(AsmToken::Register, regStr, 9902758a44e41564aafa0e50843aaedafe6b3ed7b3Chris Lattner static_cast<int64_t>(regID)); 100cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan } 10102758a44e41564aafa0e50843aaedafe6b3ed7b3Chris Lattner 102645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner // Match register name failed. If this is "db[0-7]", match it as an alias 103645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner // for dr[0-7]. 104645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner if (nextToken.getString().size() == 3 && 105645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner nextToken.getString().startswith("db")) { 106645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner int RegNo = -1; 107645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner switch (nextToken.getString()[2]) { 108645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner case '0': RegNo = X86::DR0; break; 109645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner case '1': RegNo = X86::DR1; break; 110645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner case '2': RegNo = X86::DR2; break; 111645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner case '3': RegNo = X86::DR3; break; 112645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner case '4': RegNo = X86::DR4; break; 113645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner case '5': RegNo = X86::DR5; break; 114645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner case '6': RegNo = X86::DR6; break; 115645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner case '7': RegNo = X86::DR7; break; 116645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner } 117645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner 118645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner if (RegNo != -1) { 119645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner lexDefinite(); 120645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner 121645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner // FIXME: This is completely wrong when there is a space or other 122645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner // punctuation between the % and the register name. 123645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner StringRef regStr(lexedToken.getString().data(), 124645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner lexedToken.getString().size() + 125645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner nextToken.getString().size()); 126645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner return AsmToken(AsmToken::Register, regStr, 127645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner static_cast<int64_t>(RegNo)); 128645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner } 129645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner } 130645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner 131645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner 132adabe1a92cf594fc4015f83024bc06b8687f09e3Chris Lattner return lexedToken; 133cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan } 134cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan } 135436c48485c365b399a908944ebbf4f761a4f9f6aSean Callanan} 136436c48485c365b399a908944ebbf4f761a4f9f6aSean Callanan 137436c48485c365b399a908944ebbf4f761a4f9f6aSean CallananAsmToken X86AsmLexer::LexTokenIntel() { 1387dcef4c47578befe40d488c953e3f5b328667300Sean Callanan const AsmToken &lexedToken = lexDefinite(); 1397dcef4c47578befe40d488c953e3f5b328667300Sean Callanan 1407dcef4c47578befe40d488c953e3f5b328667300Sean Callanan switch(lexedToken.getKind()) { 1417dcef4c47578befe40d488c953e3f5b328667300Sean Callanan default: 142adabe1a92cf594fc4015f83024bc06b8687f09e3Chris Lattner return lexedToken; 1437dcef4c47578befe40d488c953e3f5b328667300Sean Callanan case AsmToken::Error: 1447dcef4c47578befe40d488c953e3f5b328667300Sean Callanan SetError(Lexer->getErrLoc(), Lexer->getErr()); 145adabe1a92cf594fc4015f83024bc06b8687f09e3Chris Lattner return lexedToken; 146adabe1a92cf594fc4015f83024bc06b8687f09e3Chris Lattner case AsmToken::Identifier: { 1477dcef4c47578befe40d488c953e3f5b328667300Sean Callanan std::string upperCase = lexedToken.getString().str(); 1487dcef4c47578befe40d488c953e3f5b328667300Sean Callanan std::string lowerCase = LowercaseString(upperCase); 1497dcef4c47578befe40d488c953e3f5b328667300Sean Callanan StringRef lowerRef(lowerCase); 1507dcef4c47578befe40d488c953e3f5b328667300Sean Callanan 1517dcef4c47578befe40d488c953e3f5b328667300Sean Callanan unsigned regID = MatchRegisterName(lowerRef); 1527dcef4c47578befe40d488c953e3f5b328667300Sean Callanan 153adabe1a92cf594fc4015f83024bc06b8687f09e3Chris Lattner if (regID) 1547dcef4c47578befe40d488c953e3f5b328667300Sean Callanan return AsmToken(AsmToken::Register, 1557dcef4c47578befe40d488c953e3f5b328667300Sean Callanan lexedToken.getString(), 1567dcef4c47578befe40d488c953e3f5b328667300Sean Callanan static_cast<int64_t>(regID)); 157adabe1a92cf594fc4015f83024bc06b8687f09e3Chris Lattner return lexedToken; 1587dcef4c47578befe40d488c953e3f5b328667300Sean Callanan } 1597dcef4c47578befe40d488c953e3f5b328667300Sean Callanan } 160e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan} 161e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan 162e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callananextern "C" void LLVMInitializeX86AsmLexer() { 16394b9550a32d189704a8eae55505edf62662c0534Evan Cheng RegisterMCAsmLexer<X86AsmLexer> X(TheX86_32Target); 16494b9550a32d189704a8eae55505edf62662c0534Evan Cheng RegisterMCAsmLexer<X86AsmLexer> Y(TheX86_64Target); 165e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan} 166