1//===-- MBlazeAsmLexer.cpp - Tokenize MBlaze 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/MBlazeBaseInfo.h"
11
12#include "llvm/ADT/OwningPtr.h"
13#include "llvm/ADT/SmallVector.h"
14#include "llvm/ADT/StringExtras.h"
15
16#include "llvm/MC/MCAsmInfo.h"
17#include "llvm/MC/MCParser/MCAsmLexer.h"
18#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
19#include "llvm/MC/MCRegisterInfo.h"
20#include "llvm/MC/MCTargetAsmLexer.h"
21
22#include "llvm/Support/TargetRegistry.h"
23
24#include <string>
25#include <map>
26
27using namespace llvm;
28
29namespace {
30
31  class MBlazeBaseAsmLexer : public MCTargetAsmLexer {
32    const MCAsmInfo &AsmInfo;
33
34    const AsmToken &lexDefinite() {
35      return getLexer()->Lex();
36    }
37
38    AsmToken LexTokenUAL();
39  protected:
40    typedef std::map <std::string, unsigned> rmap_ty;
41
42    rmap_ty RegisterMap;
43
44    void InitRegisterMap(const MCRegisterInfo *info) {
45      unsigned numRegs = info->getNumRegs();
46
47      for (unsigned i = 0; i < numRegs; ++i) {
48        const char *regName = info->getName(i);
49        if (regName)
50          RegisterMap[regName] = i;
51      }
52    }
53
54    unsigned MatchRegisterName(StringRef Name) {
55      rmap_ty::iterator iter = RegisterMap.find(Name.str());
56      if (iter != RegisterMap.end())
57        return iter->second;
58      else
59        return 0;
60    }
61
62    AsmToken LexToken() {
63      if (!Lexer) {
64        SetError(SMLoc(), "No MCAsmLexer installed");
65        return AsmToken(AsmToken::Error, "", 0);
66      }
67
68      switch (AsmInfo.getAssemblerDialect()) {
69      default:
70        SetError(SMLoc(), "Unhandled dialect");
71        return AsmToken(AsmToken::Error, "", 0);
72      case 0:
73        return LexTokenUAL();
74      }
75    }
76  public:
77    MBlazeBaseAsmLexer(const Target &T, const MCAsmInfo &MAI)
78      : MCTargetAsmLexer(T), AsmInfo(MAI) {
79    }
80  };
81
82  class MBlazeAsmLexer : public MBlazeBaseAsmLexer {
83  public:
84    MBlazeAsmLexer(const Target &T, const MCRegisterInfo &MRI,
85                   const MCAsmInfo &MAI)
86      : MBlazeBaseAsmLexer(T, MAI) {
87      InitRegisterMap(&MRI);
88    }
89  };
90}
91
92AsmToken MBlazeBaseAsmLexer::LexTokenUAL() {
93  const AsmToken &lexedToken = lexDefinite();
94
95  switch (lexedToken.getKind()) {
96  default:
97    return AsmToken(lexedToken);
98  case AsmToken::Error:
99    SetError(Lexer->getErrLoc(), Lexer->getErr());
100    return AsmToken(lexedToken);
101  case AsmToken::Identifier:
102  {
103    std::string upperCase = lexedToken.getString().str();
104    std::string lowerCase = LowercaseString(upperCase);
105    StringRef lowerRef(lowerCase);
106
107    unsigned regID = MatchRegisterName(lowerRef);
108
109    if (regID) {
110      return AsmToken(AsmToken::Register,
111                      lexedToken.getString(),
112                      static_cast<int64_t>(regID));
113    } else {
114      return AsmToken(lexedToken);
115    }
116  }
117  }
118}
119
120extern "C" void LLVMInitializeMBlazeAsmLexer() {
121  RegisterMCAsmLexer<MBlazeAsmLexer> X(TheMBlazeTarget);
122}
123
124