1 //===-- X86AsmLexer.cpp - Tokenize X86 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 //===----------------------------------------------------------------------===//
10 #include "llvm/ADT/SmallVector.h"
11 #include "llvm/ADT/StringExtras.h"
12 #include "llvm/Target/TargetAsmLexer.h"
13 #include "llvm/Target/TargetRegistry.h"
14 #include "llvm/MC/MCAsmInfo.h"
15 #include "llvm/MC/MCParser/MCAsmLexer.h"
16 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
23 class X86AsmLexer
: public TargetAsmLexer
{
24 const MCAsmInfo
&AsmInfo
;
26 bool tentativeIsValid
;
27 AsmToken tentativeToken
;
29 const AsmToken
&lexTentative() {
30 tentativeToken
= getLexer()->Lex();
31 tentativeIsValid
= true;
32 return tentativeToken
;
35 const AsmToken
&lexDefinite() {
36 if (tentativeIsValid
) {
37 tentativeIsValid
= false;
38 return tentativeToken
;
40 return getLexer()->Lex();
43 AsmToken
LexTokenATT();
44 AsmToken
LexTokenIntel();
48 SetError(SMLoc(), "No MCAsmLexer installed");
49 return AsmToken(AsmToken::Error
, "", 0);
52 switch (AsmInfo
.getAssemblerDialect()) {
54 SetError(SMLoc(), "Unhandled dialect");
55 return AsmToken(AsmToken::Error
, "", 0);
59 return LexTokenIntel();
63 X86AsmLexer(const Target
&T
, const MCAsmInfo
&MAI
)
64 : TargetAsmLexer(T
), AsmInfo(MAI
), tentativeIsValid(false) {
68 } // end anonymous namespace
70 #define GET_REGISTER_MATCHER
71 #include "X86GenAsmMatcher.inc"
73 AsmToken
X86AsmLexer::LexTokenATT() {
74 AsmToken lexedToken
= lexDefinite();
76 switch (lexedToken
.getKind()) {
80 SetError(Lexer
->getErrLoc(), Lexer
->getErr());
83 case AsmToken::Percent
: {
84 const AsmToken
&nextToken
= lexTentative();
85 if (nextToken
.getKind() != AsmToken::Identifier
)
89 if (unsigned regID
= MatchRegisterName(nextToken
.getString())) {
92 // FIXME: This is completely wrong when there is a space or other
93 // punctuation between the % and the register name.
94 StringRef
regStr(lexedToken
.getString().data(),
95 lexedToken
.getString().size() +
96 nextToken
.getString().size());
98 return AsmToken(AsmToken::Register
, regStr
,
99 static_cast<int64_t>(regID
));
102 // Match register name failed. If this is "db[0-7]", match it as an alias
104 if (nextToken
.getString().size() == 3 &&
105 nextToken
.getString().startswith("db")) {
107 switch (nextToken
.getString()[2]) {
108 case '0': RegNo
= X86::DR0
; break;
109 case '1': RegNo
= X86::DR1
; break;
110 case '2': RegNo
= X86::DR2
; break;
111 case '3': RegNo
= X86::DR3
; break;
112 case '4': RegNo
= X86::DR4
; break;
113 case '5': RegNo
= X86::DR5
; break;
114 case '6': RegNo
= X86::DR6
; break;
115 case '7': RegNo
= X86::DR7
; break;
121 // FIXME: This is completely wrong when there is a space or other
122 // punctuation between the % and the register name.
123 StringRef
regStr(lexedToken
.getString().data(),
124 lexedToken
.getString().size() +
125 nextToken
.getString().size());
126 return AsmToken(AsmToken::Register
, regStr
,
127 static_cast<int64_t>(RegNo
));
137 AsmToken
X86AsmLexer::LexTokenIntel() {
138 const AsmToken
&lexedToken
= lexDefinite();
140 switch(lexedToken
.getKind()) {
143 case AsmToken::Error
:
144 SetError(Lexer
->getErrLoc(), Lexer
->getErr());
146 case AsmToken::Identifier
: {
147 std::string upperCase
= lexedToken
.getString().str();
148 std::string lowerCase
= LowercaseString(upperCase
);
149 StringRef
lowerRef(lowerCase
);
151 unsigned regID
= MatchRegisterName(lowerRef
);
154 return AsmToken(AsmToken::Register
,
155 lexedToken
.getString(),
156 static_cast<int64_t>(regID
));
162 extern "C" void LLVMInitializeX86AsmLexer() {
163 RegisterAsmLexer
<X86AsmLexer
> X(TheX86_32Target
);
164 RegisterAsmLexer
<X86AsmLexer
> Y(TheX86_64Target
);