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" 153e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h" 16a7cfc08ebe737062917b442830eb5321b0f79e89Evan Cheng#include "llvm/ADT/SmallVector.h" 17e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan 18e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callananusing namespace llvm; 19e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan 20e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanannamespace { 21e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan 2294b9550a32d189704a8eae55505edf62662c0534Evan Chengclass X86AsmLexer : public MCTargetAsmLexer { 23e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan const MCAsmInfo &AsmInfo; 24cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan 25cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan bool tentativeIsValid; 26cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan AsmToken tentativeToken; 27cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan 28cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan const AsmToken &lexTentative() { 29894c1af05fb3f0d8e2ee6565816fa220b260ed9dSean Callanan tentativeToken = getLexer()->Lex(); 30cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan tentativeIsValid = true; 31cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan return tentativeToken; 32cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan } 33cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan 34cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan const AsmToken &lexDefinite() { 35adabe1a92cf594fc4015f83024bc06b8687f09e3Chris Lattner if (tentativeIsValid) { 36cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan tentativeIsValid = false; 37cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan return tentativeToken; 38cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan } 39adabe1a92cf594fc4015f83024bc06b8687f09e3Chris Lattner return getLexer()->Lex(); 40cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan } 41436c48485c365b399a908944ebbf4f761a4f9f6aSean Callanan 42436c48485c365b399a908944ebbf4f761a4f9f6aSean Callanan AsmToken LexTokenATT(); 43436c48485c365b399a908944ebbf4f761a4f9f6aSean Callanan AsmToken LexTokenIntel(); 44e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callananprotected: 45436c48485c365b399a908944ebbf4f761a4f9f6aSean Callanan AsmToken LexToken() { 46cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan if (!Lexer) { 47cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan SetError(SMLoc(), "No MCAsmLexer installed"); 48cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan return AsmToken(AsmToken::Error, "", 0); 49cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan } 50cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan 51436c48485c365b399a908944ebbf4f761a4f9f6aSean Callanan switch (AsmInfo.getAssemblerDialect()) { 52436c48485c365b399a908944ebbf4f761a4f9f6aSean Callanan default: 53436c48485c365b399a908944ebbf4f761a4f9f6aSean Callanan SetError(SMLoc(), "Unhandled dialect"); 54436c48485c365b399a908944ebbf4f761a4f9f6aSean Callanan return AsmToken(AsmToken::Error, "", 0); 55436c48485c365b399a908944ebbf4f761a4f9f6aSean Callanan case 0: 56436c48485c365b399a908944ebbf4f761a4f9f6aSean Callanan return LexTokenATT(); 57436c48485c365b399a908944ebbf4f761a4f9f6aSean Callanan case 1: 58436c48485c365b399a908944ebbf4f761a4f9f6aSean Callanan return LexTokenIntel(); 59436c48485c365b399a908944ebbf4f761a4f9f6aSean Callanan } 60436c48485c365b399a908944ebbf4f761a4f9f6aSean Callanan } 61e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callananpublic: 621b0fc9b4182d6bd0703cdfb3b0b91d1e093c946cEvan Cheng X86AsmLexer(const Target &T, const MCRegisterInfo &MRI, const MCAsmInfo &MAI) 6394b9550a32d189704a8eae55505edf62662c0534Evan Cheng : MCTargetAsmLexer(T), AsmInfo(MAI), tentativeIsValid(false) { 64e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan } 65e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan}; 66e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan 670692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner} // end anonymous namespace 68e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan 690692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER 700692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "X86GenAsmMatcher.inc" 71cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan 72436c48485c365b399a908944ebbf4f761a4f9f6aSean CallananAsmToken X86AsmLexer::LexTokenATT() { 73adabe1a92cf594fc4015f83024bc06b8687f09e3Chris Lattner AsmToken lexedToken = lexDefinite(); 74cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan 75cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan switch (lexedToken.getKind()) { 76cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan default: 77adabe1a92cf594fc4015f83024bc06b8687f09e3Chris Lattner return lexedToken; 78cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan case AsmToken::Error: 79cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan SetError(Lexer->getErrLoc(), Lexer->getErr()); 80adabe1a92cf594fc4015f83024bc06b8687f09e3Chris Lattner return lexedToken; 81adabe1a92cf594fc4015f83024bc06b8687f09e3Chris Lattner 82adabe1a92cf594fc4015f83024bc06b8687f09e3Chris Lattner case AsmToken::Percent: { 83cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan const AsmToken &nextToken = lexTentative(); 8402758a44e41564aafa0e50843aaedafe6b3ed7b3Chris Lattner if (nextToken.getKind() != AsmToken::Identifier) 85adabe1a92cf594fc4015f83024bc06b8687f09e3Chris Lattner return lexedToken; 8602758a44e41564aafa0e50843aaedafe6b3ed7b3Chris Lattner 87cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan 8802758a44e41564aafa0e50843aaedafe6b3ed7b3Chris Lattner if (unsigned regID = MatchRegisterName(nextToken.getString())) { 8902758a44e41564aafa0e50843aaedafe6b3ed7b3Chris Lattner lexDefinite(); 90cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan 91645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner // FIXME: This is completely wrong when there is a space or other 92645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner // punctuation between the % and the register name. 9302758a44e41564aafa0e50843aaedafe6b3ed7b3Chris Lattner StringRef regStr(lexedToken.getString().data(), 9402758a44e41564aafa0e50843aaedafe6b3ed7b3Chris Lattner lexedToken.getString().size() + 9502758a44e41564aafa0e50843aaedafe6b3ed7b3Chris Lattner nextToken.getString().size()); 9602758a44e41564aafa0e50843aaedafe6b3ed7b3Chris Lattner 97adabe1a92cf594fc4015f83024bc06b8687f09e3Chris Lattner return AsmToken(AsmToken::Register, regStr, 9802758a44e41564aafa0e50843aaedafe6b3ed7b3Chris Lattner static_cast<int64_t>(regID)); 99cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan } 10002758a44e41564aafa0e50843aaedafe6b3ed7b3Chris Lattner 101645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner // Match register name failed. If this is "db[0-7]", match it as an alias 102645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner // for dr[0-7]. 103645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner if (nextToken.getString().size() == 3 && 104645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner nextToken.getString().startswith("db")) { 105645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner int RegNo = -1; 106645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner switch (nextToken.getString()[2]) { 107645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner case '0': RegNo = X86::DR0; break; 108645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner case '1': RegNo = X86::DR1; break; 109645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner case '2': RegNo = X86::DR2; break; 110645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner case '3': RegNo = X86::DR3; break; 111645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner case '4': RegNo = X86::DR4; break; 112645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner case '5': RegNo = X86::DR5; break; 113645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner case '6': RegNo = X86::DR6; break; 114645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner case '7': RegNo = X86::DR7; break; 115645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner } 116645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner 117645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner if (RegNo != -1) { 118645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner lexDefinite(); 119645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner 120645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner // FIXME: This is completely wrong when there is a space or other 121645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner // punctuation between the % and the register name. 122645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner StringRef regStr(lexedToken.getString().data(), 123645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner lexedToken.getString().size() + 124645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner nextToken.getString().size()); 125645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner return AsmToken(AsmToken::Register, regStr, 126645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner static_cast<int64_t>(RegNo)); 127645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner } 128645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner } 129645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner 130645b209c4af53c0d21292df3d506cf79d4e3ec11Chris Lattner 131adabe1a92cf594fc4015f83024bc06b8687f09e3Chris Lattner return lexedToken; 132cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan } 133cf2e3d108d6f8f692c01bd48767c7f8dd9e20dcfSean Callanan } 134436c48485c365b399a908944ebbf4f761a4f9f6aSean Callanan} 135436c48485c365b399a908944ebbf4f761a4f9f6aSean Callanan 136436c48485c365b399a908944ebbf4f761a4f9f6aSean CallananAsmToken X86AsmLexer::LexTokenIntel() { 1377dcef4c47578befe40d488c953e3f5b328667300Sean Callanan const AsmToken &lexedToken = lexDefinite(); 1387dcef4c47578befe40d488c953e3f5b328667300Sean Callanan 1397dcef4c47578befe40d488c953e3f5b328667300Sean Callanan switch(lexedToken.getKind()) { 1407dcef4c47578befe40d488c953e3f5b328667300Sean Callanan default: 141adabe1a92cf594fc4015f83024bc06b8687f09e3Chris Lattner return lexedToken; 1427dcef4c47578befe40d488c953e3f5b328667300Sean Callanan case AsmToken::Error: 1437dcef4c47578befe40d488c953e3f5b328667300Sean Callanan SetError(Lexer->getErrLoc(), Lexer->getErr()); 144adabe1a92cf594fc4015f83024bc06b8687f09e3Chris Lattner return lexedToken; 145adabe1a92cf594fc4015f83024bc06b8687f09e3Chris Lattner case AsmToken::Identifier: { 1467b135ae6d5904bca27ae81ca3c4324f8c8b855fdBenjamin Kramer unsigned regID = MatchRegisterName(lexedToken.getString().lower()); 1477dcef4c47578befe40d488c953e3f5b328667300Sean Callanan 148adabe1a92cf594fc4015f83024bc06b8687f09e3Chris Lattner if (regID) 1497dcef4c47578befe40d488c953e3f5b328667300Sean Callanan return AsmToken(AsmToken::Register, 1507dcef4c47578befe40d488c953e3f5b328667300Sean Callanan lexedToken.getString(), 1517dcef4c47578befe40d488c953e3f5b328667300Sean Callanan static_cast<int64_t>(regID)); 152adabe1a92cf594fc4015f83024bc06b8687f09e3Chris Lattner return lexedToken; 1537dcef4c47578befe40d488c953e3f5b328667300Sean Callanan } 1547dcef4c47578befe40d488c953e3f5b328667300Sean Callanan } 155e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan} 156e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan 157e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callananextern "C" void LLVMInitializeX86AsmLexer() { 15894b9550a32d189704a8eae55505edf62662c0534Evan Cheng RegisterMCAsmLexer<X86AsmLexer> X(TheX86_32Target); 15994b9550a32d189704a8eae55505edf62662c0534Evan Cheng RegisterMCAsmLexer<X86AsmLexer> Y(TheX86_64Target); 160e88f55254cde9d9443f1299b61aa6a93ec50b791Sean Callanan} 161