blob: e350515f3aa039c55fe100f47c42e6a7b64dac78 [file] [log] [blame]
Sean Callanan5bbbc372010-01-23 02:43:15 +00001//===-- X86AsmLexer.cpp - Tokenize X86 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
Sean Callanan53509642010-01-26 00:08:25 +000010#include "llvm/ADT/SmallVector.h"
Sean Callanan8bb3b9e2010-01-26 01:00:10 +000011#include "llvm/ADT/StringExtras.h"
Sean Callanan5bbbc372010-01-23 02:43:15 +000012#include "llvm/Target/TargetAsmLexer.h"
13#include "llvm/Target/TargetRegistry.h"
Sean Callanan761bd522010-01-25 21:59:20 +000014#include "llvm/MC/MCAsmInfo.h"
Sean Callanan5bbbc372010-01-23 02:43:15 +000015#include "llvm/MC/MCParser/MCAsmLexer.h"
16#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
17#include "X86.h"
18
19using namespace llvm;
20
21namespace {
22
23class X86AsmLexer : public TargetAsmLexer {
24 const MCAsmInfo &AsmInfo;
Sean Callanan53509642010-01-26 00:08:25 +000025 MCAsmLexer *Lexer;
26
27 bool tentativeIsValid;
28 AsmToken tentativeToken;
29
30 const AsmToken &lexTentative() {
31 tentativeToken = Lexer->Lex();
32 tentativeIsValid = true;
33 return tentativeToken;
34 }
35
36 const AsmToken &lexDefinite() {
37 if(tentativeIsValid) {
38 tentativeIsValid = false;
39 return tentativeToken;
40 }
41 else {
42 return Lexer->Lex();
43 }
44 }
Sean Callanan761bd522010-01-25 21:59:20 +000045
46 AsmToken LexTokenATT();
47 AsmToken LexTokenIntel();
Sean Callanan5bbbc372010-01-23 02:43:15 +000048protected:
Sean Callanan761bd522010-01-25 21:59:20 +000049 AsmToken LexToken() {
Sean Callanan53509642010-01-26 00:08:25 +000050 if (!Lexer) {
51 SetError(SMLoc(), "No MCAsmLexer installed");
52 return AsmToken(AsmToken::Error, "", 0);
53 }
54
Sean Callanan761bd522010-01-25 21:59:20 +000055 switch (AsmInfo.getAssemblerDialect()) {
56 default:
57 SetError(SMLoc(), "Unhandled dialect");
58 return AsmToken(AsmToken::Error, "", 0);
59 case 0:
60 return LexTokenATT();
61 case 1:
62 return LexTokenIntel();
63 }
64 }
Sean Callanan5bbbc372010-01-23 02:43:15 +000065public:
66 X86AsmLexer(const Target &T, const MCAsmInfo &MAI)
Sean Callanan53509642010-01-26 00:08:25 +000067 : TargetAsmLexer(T), AsmInfo(MAI), Lexer(NULL), tentativeIsValid(false) {
68 }
69
70 void InstallLexer(MCAsmLexer &L) {
71 Lexer = &L;
Sean Callanan5bbbc372010-01-23 02:43:15 +000072 }
73};
74
75}
76
Sean Callanan53509642010-01-26 00:08:25 +000077static unsigned MatchRegisterName(const StringRef &Name);
78
Sean Callanan761bd522010-01-25 21:59:20 +000079AsmToken X86AsmLexer::LexTokenATT() {
Sean Callanan53509642010-01-26 00:08:25 +000080 const AsmToken &lexedToken = lexDefinite();
81
82 switch (lexedToken.getKind()) {
83 default:
84 return AsmToken(lexedToken);
85 case AsmToken::Error:
86 SetError(Lexer->getErrLoc(), Lexer->getErr());
87 return AsmToken(lexedToken);
88 case AsmToken::Percent:
89 {
90 const AsmToken &nextToken = lexTentative();
91 if (nextToken.getKind() == AsmToken::Identifier) {
92 unsigned regID = MatchRegisterName(nextToken.getString());
93
94 if (regID) {
95 lexDefinite();
96
97 StringRef regStr(lexedToken.getString().data(),
98 lexedToken.getString().size() +
99 nextToken.getString().size());
100
101 return AsmToken(AsmToken::Register,
102 regStr,
103 static_cast<int64_t>(regID));
104 }
105 else {
106 return AsmToken(lexedToken);
107 }
108 }
109 else {
110 return AsmToken(lexedToken);
111 }
112 }
113 }
Sean Callanan761bd522010-01-25 21:59:20 +0000114}
115
116AsmToken X86AsmLexer::LexTokenIntel() {
Sean Callanan8bb3b9e2010-01-26 01:00:10 +0000117 const AsmToken &lexedToken = lexDefinite();
118
119 switch(lexedToken.getKind()) {
120 default:
121 return AsmToken(lexedToken);
122 case AsmToken::Error:
123 SetError(Lexer->getErrLoc(), Lexer->getErr());
124 return AsmToken(lexedToken);
125 case AsmToken::Identifier:
126 {
127 std::string upperCase = lexedToken.getString().str();
128 std::string lowerCase = LowercaseString(upperCase);
129 StringRef lowerRef(lowerCase);
130
131 unsigned regID = MatchRegisterName(lowerRef);
132
133 if (regID) {
134 return AsmToken(AsmToken::Register,
135 lexedToken.getString(),
136 static_cast<int64_t>(regID));
137 }
138 else {
139 return AsmToken(lexedToken);
140 }
141 }
142 }
Sean Callanan5bbbc372010-01-23 02:43:15 +0000143}
144
145extern "C" void LLVMInitializeX86AsmLexer() {
146 RegisterAsmLexer<X86AsmLexer> X(TheX86_32Target);
147 RegisterAsmLexer<X86AsmLexer> Y(TheX86_64Target);
148}
149
Sean Callanan53509642010-01-26 00:08:25 +0000150#define REGISTERS_ONLY
151#include "../X86GenAsmMatcher.inc"
152#undef REGISTERS_ONLY