blob: f35cb10db3d78e2b68c3c16b38ffa0bbf1d2b8e4 [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 Callanan5bbbc372010-01-23 02:43:15 +000011#include "llvm/Target/TargetAsmLexer.h"
12#include "llvm/Target/TargetRegistry.h"
Sean Callanan761bd522010-01-25 21:59:20 +000013#include "llvm/MC/MCAsmInfo.h"
Sean Callanan5bbbc372010-01-23 02:43:15 +000014#include "llvm/MC/MCParser/MCAsmLexer.h"
15#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
16#include "X86.h"
17
18using namespace llvm;
19
20namespace {
21
22class X86AsmLexer : public TargetAsmLexer {
23 const MCAsmInfo &AsmInfo;
Sean Callanan53509642010-01-26 00:08:25 +000024 MCAsmLexer *Lexer;
25
26 bool tentativeIsValid;
27 AsmToken tentativeToken;
28
29 const AsmToken &lexTentative() {
30 tentativeToken = Lexer->Lex();
31 tentativeIsValid = true;
32 return tentativeToken;
33 }
34
35 const AsmToken &lexDefinite() {
36 if(tentativeIsValid) {
37 tentativeIsValid = false;
38 return tentativeToken;
39 }
40 else {
41 return Lexer->Lex();
42 }
43 }
Sean Callanan761bd522010-01-25 21:59:20 +000044
45 AsmToken LexTokenATT();
46 AsmToken LexTokenIntel();
Sean Callanan5bbbc372010-01-23 02:43:15 +000047protected:
Sean Callanan761bd522010-01-25 21:59:20 +000048 AsmToken LexToken() {
Sean Callanan53509642010-01-26 00:08:25 +000049 if (!Lexer) {
50 SetError(SMLoc(), "No MCAsmLexer installed");
51 return AsmToken(AsmToken::Error, "", 0);
52 }
53
Sean Callanan761bd522010-01-25 21:59:20 +000054 switch (AsmInfo.getAssemblerDialect()) {
55 default:
56 SetError(SMLoc(), "Unhandled dialect");
57 return AsmToken(AsmToken::Error, "", 0);
58 case 0:
59 return LexTokenATT();
60 case 1:
61 return LexTokenIntel();
62 }
63 }
Sean Callanan5bbbc372010-01-23 02:43:15 +000064public:
65 X86AsmLexer(const Target &T, const MCAsmInfo &MAI)
Sean Callanan53509642010-01-26 00:08:25 +000066 : TargetAsmLexer(T), AsmInfo(MAI), Lexer(NULL), tentativeIsValid(false) {
67 }
68
69 void InstallLexer(MCAsmLexer &L) {
70 Lexer = &L;
Sean Callanan5bbbc372010-01-23 02:43:15 +000071 }
72};
73
74}
75
Sean Callanan53509642010-01-26 00:08:25 +000076static unsigned MatchRegisterName(const StringRef &Name);
77
Sean Callanan761bd522010-01-25 21:59:20 +000078AsmToken X86AsmLexer::LexTokenATT() {
Sean Callanan53509642010-01-26 00:08:25 +000079 const AsmToken &lexedToken = lexDefinite();
80
81 switch (lexedToken.getKind()) {
82 default:
83 return AsmToken(lexedToken);
84 case AsmToken::Error:
85 SetError(Lexer->getErrLoc(), Lexer->getErr());
86 return AsmToken(lexedToken);
87 case AsmToken::Percent:
88 {
89 const AsmToken &nextToken = lexTentative();
90 if (nextToken.getKind() == AsmToken::Identifier) {
91 unsigned regID = MatchRegisterName(nextToken.getString());
92
93 if (regID) {
94 lexDefinite();
95
96 StringRef regStr(lexedToken.getString().data(),
97 lexedToken.getString().size() +
98 nextToken.getString().size());
99
100 return AsmToken(AsmToken::Register,
101 regStr,
102 static_cast<int64_t>(regID));
103 }
104 else {
105 return AsmToken(lexedToken);
106 }
107 }
108 else {
109 return AsmToken(lexedToken);
110 }
111 }
112 }
Sean Callanan761bd522010-01-25 21:59:20 +0000113}
114
115AsmToken X86AsmLexer::LexTokenIntel() {
Sean Callanan5bbbc372010-01-23 02:43:15 +0000116 return AsmToken(AsmToken::Error, "", 0);
117}
118
119extern "C" void LLVMInitializeX86AsmLexer() {
120 RegisterAsmLexer<X86AsmLexer> X(TheX86_32Target);
121 RegisterAsmLexer<X86AsmLexer> Y(TheX86_64Target);
122}
123
Sean Callanan53509642010-01-26 00:08:25 +0000124#define REGISTERS_ONLY
125#include "../X86GenAsmMatcher.inc"
126#undef REGISTERS_ONLY