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