1 //===-- ARMAsmLexer.cpp - Tokenize ARM assembly to AsmTokens --------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 #include "ARMTargetMachine.h"
13 #include "llvm/MC/MCAsmInfo.h"
14 #include "llvm/MC/MCParser/MCAsmLexer.h"
15 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
17 #include "llvm/Target/TargetAsmLexer.h"
18 #include "llvm/Target/TargetMachine.h"
19 #include "llvm/Target/TargetRegistry.h"
21 #include "llvm/ADT/OwningPtr.h"
22 #include "llvm/ADT/SmallVector.h"
23 #include "llvm/ADT/StringExtras.h"
24 #include "llvm/ADT/StringSwitch.h"
33 class ARMBaseAsmLexer
: public TargetAsmLexer
{
34 const MCAsmInfo
&AsmInfo
;
36 const AsmToken
&lexDefinite() {
37 return getLexer()->Lex();
40 AsmToken
LexTokenUAL();
42 typedef std::map
<std::string
, unsigned> rmap_ty
;
46 void InitRegisterMap(const TargetRegisterInfo
*info
) {
47 unsigned numRegs
= info
->getNumRegs();
49 for (unsigned i
= 0; i
< numRegs
; ++i
) {
50 const char *regName
= info
->getName(i
);
52 RegisterMap
[regName
] = i
;
56 unsigned MatchRegisterName(StringRef Name
) {
57 rmap_ty::iterator iter
= RegisterMap
.find(Name
.str());
58 if (iter
!= RegisterMap
.end())
66 SetError(SMLoc(), "No MCAsmLexer installed");
67 return AsmToken(AsmToken::Error
, "", 0);
70 switch (AsmInfo
.getAssemblerDialect()) {
72 SetError(SMLoc(), "Unhandled dialect");
73 return AsmToken(AsmToken::Error
, "", 0);
79 ARMBaseAsmLexer(const Target
&T
, const MCAsmInfo
&MAI
)
80 : TargetAsmLexer(T
), AsmInfo(MAI
) {
84 class ARMAsmLexer
: public ARMBaseAsmLexer
{
86 ARMAsmLexer(const Target
&T
, const MCAsmInfo
&MAI
)
87 : ARMBaseAsmLexer(T
, MAI
) {
88 std::string
tripleString("arm-unknown-unknown");
89 std::string featureString
;
91 OwningPtr
<const TargetMachine
>
92 targetMachine(T
.createTargetMachine(tripleString
, CPU
, featureString
));
93 InitRegisterMap(targetMachine
->getRegisterInfo());
97 class ThumbAsmLexer
: public ARMBaseAsmLexer
{
99 ThumbAsmLexer(const Target
&T
, const MCAsmInfo
&MAI
)
100 : ARMBaseAsmLexer(T
, MAI
) {
101 std::string
tripleString("thumb-unknown-unknown");
102 std::string featureString
;
104 OwningPtr
<const TargetMachine
>
105 targetMachine(T
.createTargetMachine(tripleString
, CPU
, featureString
));
106 InitRegisterMap(targetMachine
->getRegisterInfo());
110 } // end anonymous namespace
112 AsmToken
ARMBaseAsmLexer::LexTokenUAL() {
113 const AsmToken
&lexedToken
= lexDefinite();
115 switch (lexedToken
.getKind()) {
117 case AsmToken::Error
:
118 SetError(Lexer
->getErrLoc(), Lexer
->getErr());
120 case AsmToken::Identifier
: {
121 std::string upperCase
= lexedToken
.getString().str();
122 std::string lowerCase
= LowercaseString(upperCase
);
123 StringRef
lowerRef(lowerCase
);
125 unsigned regID
= MatchRegisterName(lowerRef
);
126 // Check for register aliases.
131 // FIXME: Some assemblers support lots of others. Do we want them all?
133 regID
= StringSwitch
<unsigned>(lowerCase
)
134 .Case("r13", ARM::SP
)
135 .Case("r14", ARM::LR
)
136 .Case("r15", ARM::PC
)
137 .Case("ip", ARM::R12
)
142 return AsmToken(AsmToken::Register
,
143 lexedToken
.getString(),
144 static_cast<int64_t>(regID
));
148 return AsmToken(lexedToken
);
151 extern "C" void LLVMInitializeARMAsmLexer() {
152 RegisterAsmLexer
<ARMAsmLexer
> X(TheARMTarget
);
153 RegisterAsmLexer
<ThumbAsmLexer
> Y(TheThumbTarget
);