blob: edbe0e0082a8ca109b25aaee0128e29679179ae4 [file] [log] [blame]
Chris Lattner847da552010-07-20 18:25:19 +00001//===-- EDToken.cpp - LLVM Enhanced Disassembler --------------------------===//
Sean Callananee5dfd42010-02-01 08:49:35 +00002//
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// This file implements the Enhanced Disassembler library's token class. The
11// token is responsible for vending information about the token, such as its
12// type and logical value.
13//
14//===----------------------------------------------------------------------===//
15
Sean Callananee5dfd42010-02-01 08:49:35 +000016#include "EDToken.h"
Chris Lattner847da552010-07-20 18:25:19 +000017#include "EDDisassembler.h"
Sean Callananee5dfd42010-02-01 08:49:35 +000018#include "llvm/MC/MCParser/MCAsmLexer.h"
19#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
Chris Lattner847da552010-07-20 18:25:19 +000020#include "llvm/ADT/SmallVector.h"
Sean Callananee5dfd42010-02-01 08:49:35 +000021using namespace llvm;
22
23EDToken::EDToken(StringRef str,
24 enum tokenType type,
25 uint64_t localType,
26 EDDisassembler &disassembler) :
27 Disassembler(disassembler),
28 Str(str),
29 Type(type),
30 LocalType(localType),
31 OperandID(-1) {
32}
33
34EDToken::~EDToken() {
35}
36
37void EDToken::makeLiteral(bool sign, uint64_t absoluteValue) {
38 Type = kTokenLiteral;
39 LiteralSign = sign;
40 LiteralAbsoluteValue = absoluteValue;
41}
42
43void EDToken::makeRegister(unsigned registerID) {
44 Type = kTokenRegister;
45 RegisterID = registerID;
46}
47
48void EDToken::setOperandID(int operandID) {
49 OperandID = operandID;
50}
51
52enum EDToken::tokenType EDToken::type() const {
53 return Type;
54}
55
56uint64_t EDToken::localType() const {
57 return LocalType;
58}
59
60StringRef EDToken::string() const {
61 return Str;
62}
63
64int EDToken::operandID() const {
65 return OperandID;
66}
67
68int EDToken::literalSign() const {
Sean Callanan8f993b82010-04-08 00:48:21 +000069 if (Type != kTokenLiteral)
Sean Callananee5dfd42010-02-01 08:49:35 +000070 return -1;
71 return (LiteralSign ? 1 : 0);
72}
73
74int EDToken::literalAbsoluteValue(uint64_t &value) const {
Sean Callanan8f993b82010-04-08 00:48:21 +000075 if (Type != kTokenLiteral)
Sean Callananee5dfd42010-02-01 08:49:35 +000076 return -1;
77 value = LiteralAbsoluteValue;
78 return 0;
79}
80
81int EDToken::registerID(unsigned &registerID) const {
Sean Callanan8f993b82010-04-08 00:48:21 +000082 if (Type != kTokenRegister)
Sean Callananee5dfd42010-02-01 08:49:35 +000083 return -1;
84 registerID = RegisterID;
85 return 0;
86}
87
88int EDToken::tokenize(std::vector<EDToken*> &tokens,
89 std::string &str,
90 const char *operandOrder,
91 EDDisassembler &disassembler) {
92 SmallVector<MCParsedAsmOperand*, 5> parsedOperands;
93 SmallVector<AsmToken, 10> asmTokens;
94
Sean Callanan8f993b82010-04-08 00:48:21 +000095 if (disassembler.parseInst(parsedOperands, asmTokens, str))
Sean Callanan40827c42011-08-19 18:23:06 +000096 {
97 for (unsigned i = 0, e = parsedOperands.size(); i != e; ++i)
98 delete parsedOperands[i];
Sean Callanande5dac12010-02-09 01:00:18 +000099 return -1;
Sean Callanan40827c42011-08-19 18:23:06 +0000100 }
101
Sean Callananee5dfd42010-02-01 08:49:35 +0000102 SmallVectorImpl<MCParsedAsmOperand*>::iterator operandIterator;
103 unsigned int operandIndex;
104 SmallVectorImpl<AsmToken>::iterator tokenIterator;
105
106 operandIterator = parsedOperands.begin();
107 operandIndex = 0;
108
109 bool readOpcode = false;
110
Sean Callanan2d581472010-02-09 01:50:54 +0000111 const char *wsPointer = asmTokens.begin()->getLoc().getPointer();
112
Sean Callananee5dfd42010-02-01 08:49:35 +0000113 for (tokenIterator = asmTokens.begin();
114 tokenIterator != asmTokens.end();
115 ++tokenIterator) {
116 SMLoc tokenLoc = tokenIterator->getLoc();
117
Sean Callanan2d581472010-02-09 01:50:54 +0000118 const char *tokenPointer = tokenLoc.getPointer();
119
Sean Callanan8f993b82010-04-08 00:48:21 +0000120 if (tokenPointer > wsPointer) {
Sean Callanan2d581472010-02-09 01:50:54 +0000121 unsigned long wsLength = tokenPointer - wsPointer;
122
123 EDToken *whitespaceToken = new EDToken(StringRef(wsPointer, wsLength),
124 EDToken::kTokenWhitespace,
125 0,
126 disassembler);
127
128 tokens.push_back(whitespaceToken);
129 }
130
131 wsPointer = tokenPointer + tokenIterator->getString().size();
132
Sean Callananee5dfd42010-02-01 08:49:35 +0000133 while (operandIterator != parsedOperands.end() &&
134 tokenLoc.getPointer() >
135 (*operandIterator)->getEndLoc().getPointer()) {
136 ++operandIterator;
137 ++operandIndex;
138 }
139
140 EDToken *token;
141
142 switch (tokenIterator->getKind()) {
143 case AsmToken::Identifier:
144 if (!readOpcode) {
145 token = new EDToken(tokenIterator->getString(),
146 EDToken::kTokenOpcode,
147 (uint64_t)tokenIterator->getKind(),
148 disassembler);
149 readOpcode = true;
150 break;
151 }
152 // any identifier that isn't an opcode is mere punctuation; so we fall
153 // through
154 default:
155 token = new EDToken(tokenIterator->getString(),
156 EDToken::kTokenPunctuation,
157 (uint64_t)tokenIterator->getKind(),
158 disassembler);
159 break;
160 case AsmToken::Integer:
161 {
162 token = new EDToken(tokenIterator->getString(),
163 EDToken::kTokenLiteral,
164 (uint64_t)tokenIterator->getKind(),
165 disassembler);
166
167 int64_t intVal = tokenIterator->getIntVal();
168
Sean Callanan8f993b82010-04-08 00:48:21 +0000169 if (intVal < 0)
Sean Callananee5dfd42010-02-01 08:49:35 +0000170 token->makeLiteral(true, -intVal);
171 else
172 token->makeLiteral(false, intVal);
173 break;
174 }
175 case AsmToken::Register:
176 {
177 token = new EDToken(tokenIterator->getString(),
178 EDToken::kTokenLiteral,
179 (uint64_t)tokenIterator->getKind(),
180 disassembler);
181
182 token->makeRegister((unsigned)tokenIterator->getRegVal());
183 break;
184 }
185 }
186
Sean Callanan8f993b82010-04-08 00:48:21 +0000187 if (operandIterator != parsedOperands.end() &&
Sean Callananee5dfd42010-02-01 08:49:35 +0000188 tokenLoc.getPointer() >=
189 (*operandIterator)->getStartLoc().getPointer()) {
Sean Callanande5dac12010-02-09 01:00:18 +0000190 /// operandIndex == 0 means the operand is the instruction (which the
191 /// AsmParser treats as an operand but edis does not). We therefore skip
192 /// operandIndex == 0 and subtract 1 from all other operand indices.
193
Sean Callanan8f993b82010-04-08 00:48:21 +0000194 if (operandIndex > 0)
Sean Callanande5dac12010-02-09 01:00:18 +0000195 token->setOperandID(operandOrder[operandIndex - 1]);
Sean Callananee5dfd42010-02-01 08:49:35 +0000196 }
197
198 tokens.push_back(token);
199 }
200
Benjamin Kramerf26be1e2011-02-24 11:03:19 +0000201 // Free any parsed operands.
202 for (unsigned i = 0, e = parsedOperands.size(); i != e; ++i)
203 delete parsedOperands[i];
204
Sean Callananee5dfd42010-02-01 08:49:35 +0000205 return 0;
206}
207
208int EDToken::getString(const char*& buf) {
Sean Callanan8f993b82010-04-08 00:48:21 +0000209 if (PermStr.length() == 0) {
Sean Callananee5dfd42010-02-01 08:49:35 +0000210 PermStr = Str.str();
211 }
212 buf = PermStr.c_str();
213 return 0;
214}