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 } 139