blob: 9408305d4bbeb37331e8f6611166fac65c488d73 [file] [log] [blame]
Sean Callananee5dfd42010-02-01 08:49:35 +00001//===-EDToken.cpp - LLVM Enhanced Disassembler ----------------------------===//
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// 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
16#include "EDDisassembler.h"
17#include "EDToken.h"
18
19#include "llvm/ADT/SmallVector.h"
20#include "llvm/MC/MCParser/MCAsmLexer.h"
21#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
22
23using namespace llvm;
24
25EDToken::EDToken(StringRef str,
26 enum tokenType type,
27 uint64_t localType,
28 EDDisassembler &disassembler) :
29 Disassembler(disassembler),
30 Str(str),
31 Type(type),
32 LocalType(localType),
33 OperandID(-1) {
34}
35
36EDToken::~EDToken() {
37}
38
39void EDToken::makeLiteral(bool sign, uint64_t absoluteValue) {
40 Type = kTokenLiteral;
41 LiteralSign = sign;
42 LiteralAbsoluteValue = absoluteValue;
43}
44
45void EDToken::makeRegister(unsigned registerID) {
46 Type = kTokenRegister;
47 RegisterID = registerID;
48}
49
50void EDToken::setOperandID(int operandID) {
51 OperandID = operandID;
52}
53
54enum EDToken::tokenType EDToken::type() const {
55 return Type;
56}
57
58uint64_t EDToken::localType() const {
59 return LocalType;
60}
61
62StringRef EDToken::string() const {
63 return Str;
64}
65
66int EDToken::operandID() const {
67 return OperandID;
68}
69
70int EDToken::literalSign() const {
71 if(Type != kTokenLiteral)
72 return -1;
73 return (LiteralSign ? 1 : 0);
74}
75
76int EDToken::literalAbsoluteValue(uint64_t &value) const {
77 if(Type != kTokenLiteral)
78 return -1;
79 value = LiteralAbsoluteValue;
80 return 0;
81}
82
83int EDToken::registerID(unsigned &registerID) const {
84 if(Type != kTokenRegister)
85 return -1;
86 registerID = RegisterID;
87 return 0;
88}
89
90int EDToken::tokenize(std::vector<EDToken*> &tokens,
91 std::string &str,
92 const char *operandOrder,
93 EDDisassembler &disassembler) {
94 SmallVector<MCParsedAsmOperand*, 5> parsedOperands;
95 SmallVector<AsmToken, 10> asmTokens;
96
Sean Callanande5dac12010-02-09 01:00:18 +000097 if(disassembler.parseInst(parsedOperands, asmTokens, str))
98 return -1;
Sean Callananee5dfd42010-02-01 08:49:35 +000099
100 SmallVectorImpl<MCParsedAsmOperand*>::iterator operandIterator;
101 unsigned int operandIndex;
102 SmallVectorImpl<AsmToken>::iterator tokenIterator;
103
104 operandIterator = parsedOperands.begin();
105 operandIndex = 0;
106
107 bool readOpcode = false;
108
109 for (tokenIterator = asmTokens.begin();
110 tokenIterator != asmTokens.end();
111 ++tokenIterator) {
112 SMLoc tokenLoc = tokenIterator->getLoc();
113
114 while (operandIterator != parsedOperands.end() &&
115 tokenLoc.getPointer() >
116 (*operandIterator)->getEndLoc().getPointer()) {
117 ++operandIterator;
118 ++operandIndex;
119 }
120
121 EDToken *token;
122
123 switch (tokenIterator->getKind()) {
124 case AsmToken::Identifier:
125 if (!readOpcode) {
126 token = new EDToken(tokenIterator->getString(),
127 EDToken::kTokenOpcode,
128 (uint64_t)tokenIterator->getKind(),
129 disassembler);
130 readOpcode = true;
131 break;
132 }
133 // any identifier that isn't an opcode is mere punctuation; so we fall
134 // through
135 default:
136 token = new EDToken(tokenIterator->getString(),
137 EDToken::kTokenPunctuation,
138 (uint64_t)tokenIterator->getKind(),
139 disassembler);
140 break;
141 case AsmToken::Integer:
142 {
143 token = new EDToken(tokenIterator->getString(),
144 EDToken::kTokenLiteral,
145 (uint64_t)tokenIterator->getKind(),
146 disassembler);
147
148 int64_t intVal = tokenIterator->getIntVal();
149
150 if(intVal < 0)
151 token->makeLiteral(true, -intVal);
152 else
153 token->makeLiteral(false, intVal);
154 break;
155 }
156 case AsmToken::Register:
157 {
158 token = new EDToken(tokenIterator->getString(),
159 EDToken::kTokenLiteral,
160 (uint64_t)tokenIterator->getKind(),
161 disassembler);
162
163 token->makeRegister((unsigned)tokenIterator->getRegVal());
164 break;
165 }
166 }
167
168 if(operandIterator != parsedOperands.end() &&
169 tokenLoc.getPointer() >=
170 (*operandIterator)->getStartLoc().getPointer()) {
Sean Callanande5dac12010-02-09 01:00:18 +0000171 /// operandIndex == 0 means the operand is the instruction (which the
172 /// AsmParser treats as an operand but edis does not). We therefore skip
173 /// operandIndex == 0 and subtract 1 from all other operand indices.
174
175 if(operandIndex > 0)
176 token->setOperandID(operandOrder[operandIndex - 1]);
Sean Callananee5dfd42010-02-01 08:49:35 +0000177 }
178
179 tokens.push_back(token);
180 }
181
182 return 0;
183}
184
185int EDToken::getString(const char*& buf) {
186 if(PermStr.length() == 0) {
187 PermStr = Str.str();
188 }
189 buf = PermStr.c_str();
190 return 0;
191}