]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - contrib/llvm/lib/Target/ARM/AsmParser/ARMAsmLexer.cpp
MFC r240780, r252468:
[FreeBSD/stable/9.git] / contrib / llvm / lib / Target / ARM / AsmParser / ARMAsmLexer.cpp
1 //===-- ARMAsmLexer.cpp - Tokenize ARM 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/ARMBaseInfo.h"
11
12 #include "llvm/MC/MCAsmInfo.h"
13 #include "llvm/MC/MCParser/MCAsmLexer.h"
14 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
15 #include "llvm/MC/MCRegisterInfo.h"
16 #include "llvm/MC/MCTargetAsmLexer.h"
17
18 #include "llvm/Support/TargetRegistry.h"
19
20 #include "llvm/ADT/StringSwitch.h"
21
22 #include <string>
23 #include <map>
24
25 using namespace llvm;
26
27 namespace {
28
29 class ARMBaseAsmLexer : public MCTargetAsmLexer {
30   const MCAsmInfo &AsmInfo;
31
32   const AsmToken &lexDefinite() {
33     return getLexer()->Lex();
34   }
35
36   AsmToken LexTokenUAL();
37 protected:
38   typedef std::map <std::string, unsigned> rmap_ty;
39
40   rmap_ty RegisterMap;
41
42   void InitRegisterMap(const MCRegisterInfo *info) {
43     unsigned numRegs = info->getNumRegs();
44
45     for (unsigned i = 0; i < numRegs; ++i) {
46       const char *regName = info->getName(i);
47       if (regName)
48         RegisterMap[regName] = i;
49     }
50   }
51
52   unsigned MatchRegisterName(StringRef Name) {
53     rmap_ty::iterator iter = RegisterMap.find(Name.str());
54     if (iter != RegisterMap.end())
55       return iter->second;
56     else
57       return 0;
58   }
59
60   AsmToken LexToken() {
61     if (!Lexer) {
62       SetError(SMLoc(), "No MCAsmLexer installed");
63       return AsmToken(AsmToken::Error, "", 0);
64     }
65
66     switch (AsmInfo.getAssemblerDialect()) {
67     default:
68       SetError(SMLoc(), "Unhandled dialect");
69       return AsmToken(AsmToken::Error, "", 0);
70     case 0:
71       return LexTokenUAL();
72     }
73   }
74 public:
75   ARMBaseAsmLexer(const Target &T, const MCAsmInfo &MAI)
76     : MCTargetAsmLexer(T), AsmInfo(MAI) {
77   }
78 };
79
80 class ARMAsmLexer : public ARMBaseAsmLexer {
81 public:
82   ARMAsmLexer(const Target &T, const MCRegisterInfo &MRI, const MCAsmInfo &MAI)
83     : ARMBaseAsmLexer(T, MAI) {
84     InitRegisterMap(&MRI);
85   }
86 };
87
88 class ThumbAsmLexer : public ARMBaseAsmLexer {
89 public:
90   ThumbAsmLexer(const Target &T, const MCRegisterInfo &MRI,const MCAsmInfo &MAI)
91     : ARMBaseAsmLexer(T, MAI) {
92     InitRegisterMap(&MRI);
93   }
94 };
95
96 } // end anonymous namespace
97
98 AsmToken ARMBaseAsmLexer::LexTokenUAL() {
99   const AsmToken &lexedToken = lexDefinite();
100
101   switch (lexedToken.getKind()) {
102   default: break;
103   case AsmToken::Error:
104     SetError(Lexer->getErrLoc(), Lexer->getErr());
105     break;
106   case AsmToken::Identifier: {
107     std::string lowerCase = lexedToken.getString().lower();
108
109     unsigned regID = MatchRegisterName(lowerCase);
110     // Check for register aliases.
111     //   r13 -> sp
112     //   r14 -> lr
113     //   r15 -> pc
114     //   ip  -> r12
115     //   FIXME: Some assemblers support lots of others. Do we want them all?
116     if (!regID) {
117       regID = StringSwitch<unsigned>(lowerCase)
118         .Case("r13", ARM::SP)
119         .Case("r14", ARM::LR)
120         .Case("r15", ARM::PC)
121         .Case("ip", ARM::R12)
122         .Default(0);
123     }
124
125     if (regID)
126       return AsmToken(AsmToken::Register,
127                       lexedToken.getString(),
128                       static_cast<int64_t>(regID));
129   }
130   }
131
132   return AsmToken(lexedToken);
133 }
134
135 extern "C" void LLVMInitializeARMAsmLexer() {
136   RegisterMCAsmLexer<ARMAsmLexer> X(TheARMTarget);
137   RegisterMCAsmLexer<ThumbAsmLexer> Y(TheThumbTarget);
138 }