1 //===-- X86AsmLexer.cpp - Tokenize X86 assembly to AsmTokens --------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "MCTargetDesc/X86BaseInfo.h" 11 #include "llvm/MC/MCAsmInfo.h" 12 #include "llvm/MC/MCParser/MCAsmLexer.h" 13 #include "llvm/MC/MCParser/MCParsedAsmOperand.h" 14 #include "llvm/MC/MCTargetAsmLexer.h" 15 #include "llvm/Support/TargetRegistry.h" 16 #include "llvm/ADT/SmallVector.h" 17 18 using namespace llvm; 19 20 namespace { 21 22 class X86AsmLexer : public MCTargetAsmLexer { 23 const MCAsmInfo &AsmInfo; 24 25 bool tentativeIsValid; 26 AsmToken tentativeToken; 27 28 const AsmToken &lexTentative() { 29 tentativeToken = getLexer()->Lex(); 30 tentativeIsValid = true; 31 return tentativeToken; 32 } 33 34 const AsmToken &lexDefinite() { 35 if (tentativeIsValid) { 36 tentativeIsValid = false; 37 return tentativeToken; 38 } 39 return getLexer()->Lex(); 40 } 41 42 AsmToken LexTokenATT(); 43 AsmToken LexTokenIntel(); 44 protected: 45 AsmToken LexToken() { 46 if (!Lexer) { 47 SetError(SMLoc(), "No MCAsmLexer installed"); 48 return AsmToken(AsmToken::Error, "", 0); 49 } 50 51 switch (AsmInfo.getAssemblerDialect()) { 52 default: 53 SetError(SMLoc(), "Unhandled dialect"); 54 return AsmToken(AsmToken::Error, "", 0); 55 case 0: 56 return LexTokenATT(); 57 case 1: 58 return LexTokenIntel(); 59 } 60 } 61 public: 62 X86AsmLexer(const Target &T, const MCRegisterInfo &MRI, const MCAsmInfo &MAI) 63 : MCTargetAsmLexer(T), AsmInfo(MAI), tentativeIsValid(false) { 64 } 65 }; 66 67 } // end anonymous namespace 68 69 #define GET_REGISTER_MATCHER 70 #include "X86GenAsmMatcher.inc" 71 72 AsmToken X86AsmLexer::LexTokenATT() { 73 AsmToken lexedToken = lexDefinite(); 74 75 switch (lexedToken.getKind()) { 76 default: 77 return lexedToken; 78 case AsmToken::Error: 79 SetError(Lexer->getErrLoc(), Lexer->getErr()); 80 return lexedToken; 81 82 case AsmToken::Percent: { 83 const AsmToken &nextToken = lexTentative(); 84 if (nextToken.getKind() != AsmToken::Identifier) 85 return lexedToken; 86 87 88 if (unsigned regID = MatchRegisterName(nextToken.getString())) { 89 lexDefinite(); 90 91 // FIXME: This is completely wrong when there is a space or other 92 // punctuation between the % and the register name. 93 StringRef regStr(lexedToken.getString().data(), 94 lexedToken.getString().size() + 95 nextToken.getString().size()); 96 97 return AsmToken(AsmToken::Register, regStr, 98 static_cast<int64_t>(regID)); 99 } 100 101 // Match register name failed. If this is "db[0-7]", match it as an alias 102 // for dr[0-7]. 103 if (nextToken.getString().size() == 3 && 104 nextToken.getString().startswith("db")) { 105 int RegNo = -1; 106 switch (nextToken.getString()[2]) { 107 case '0': RegNo = X86::DR0; break; 108 case '1': RegNo = X86::DR1; break; 109 case '2': RegNo = X86::DR2; break; 110 case '3': RegNo = X86::DR3; break; 111 case '4': RegNo = X86::DR4; break; 112 case '5': RegNo = X86::DR5; break; 113 case '6': RegNo = X86::DR6; break; 114 case '7': RegNo = X86::DR7; break; 115 } 116 117 if (RegNo != -1) { 118 lexDefinite(); 119 120 // FIXME: This is completely wrong when there is a space or other 121 // punctuation between the % and the register name. 122 StringRef regStr(lexedToken.getString().data(), 123 lexedToken.getString().size() + 124 nextToken.getString().size()); 125 return AsmToken(AsmToken::Register, regStr, 126 static_cast<int64_t>(RegNo)); 127 } 128 } 129 130 131 return lexedToken; 132 } 133 } 134 } 135 136 AsmToken X86AsmLexer::LexTokenIntel() { 137 const AsmToken &lexedToken = lexDefinite(); 138 139 switch(lexedToken.getKind()) { 140 default: 141 return lexedToken; 142 case AsmToken::Error: 143 SetError(Lexer->getErrLoc(), Lexer->getErr()); 144 return lexedToken; 145 case AsmToken::Identifier: { 146 unsigned regID = MatchRegisterName(lexedToken.getString().lower()); 147 148 if (regID) 149 return AsmToken(AsmToken::Register, 150 lexedToken.getString(), 151 static_cast<int64_t>(regID)); 152 return lexedToken; 153 } 154 } 155 } 156 157 extern "C" void LLVMInitializeX86AsmLexer() { 158 RegisterMCAsmLexer<X86AsmLexer> X(TheX86_32Target); 159 RegisterMCAsmLexer<X86AsmLexer> Y(TheX86_64Target); 160 } 161