blob: 6b67e624e8c2ddf83fa4030ed508bdeea26b444b [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
97 disassembler.parseInst(parsedOperands, asmTokens, str);
98
99 SmallVectorImpl<MCParsedAsmOperand*>::iterator operandIterator;
100 unsigned int operandIndex;
101 SmallVectorImpl<AsmToken>::iterator tokenIterator;
102
103 operandIterator = parsedOperands.begin();
104 operandIndex = 0;
105
106 bool readOpcode = false;
107
108 for (tokenIterator = asmTokens.begin();
109 tokenIterator != asmTokens.end();
110 ++tokenIterator) {
111 SMLoc tokenLoc = tokenIterator->getLoc();
112
113 while (operandIterator != parsedOperands.end() &&
114 tokenLoc.getPointer() >
115 (*operandIterator)->getEndLoc().getPointer()) {
116 ++operandIterator;
117 ++operandIndex;
118 }
119
120 EDToken *token;
121
122 switch (tokenIterator->getKind()) {
123 case AsmToken::Identifier:
124 if (!readOpcode) {
125 token = new EDToken(tokenIterator->getString(),
126 EDToken::kTokenOpcode,
127 (uint64_t)tokenIterator->getKind(),
128 disassembler);
129 readOpcode = true;
130 break;
131 }
132 // any identifier that isn't an opcode is mere punctuation; so we fall
133 // through
134 default:
135 token = new EDToken(tokenIterator->getString(),
136 EDToken::kTokenPunctuation,
137 (uint64_t)tokenIterator->getKind(),
138 disassembler);
139 break;
140 case AsmToken::Integer:
141 {
142 token = new EDToken(tokenIterator->getString(),
143 EDToken::kTokenLiteral,
144 (uint64_t)tokenIterator->getKind(),
145 disassembler);
146
147 int64_t intVal = tokenIterator->getIntVal();
148
149 if(intVal < 0)
150 token->makeLiteral(true, -intVal);
151 else
152 token->makeLiteral(false, intVal);
153 break;
154 }
155 case AsmToken::Register:
156 {
157 token = new EDToken(tokenIterator->getString(),
158 EDToken::kTokenLiteral,
159 (uint64_t)tokenIterator->getKind(),
160 disassembler);
161
162 token->makeRegister((unsigned)tokenIterator->getRegVal());
163 break;
164 }
165 }
166
167 if(operandIterator != parsedOperands.end() &&
168 tokenLoc.getPointer() >=
169 (*operandIterator)->getStartLoc().getPointer()) {
170 token->setOperandID(operandOrder[operandIndex]);
171 }
172
173 tokens.push_back(token);
174 }
175
176 return 0;
177}
178
179int EDToken::getString(const char*& buf) {
180 if(PermStr.length() == 0) {
181 PermStr = Str.str();
182 }
183 buf = PermStr.c_str();
184 return 0;
185}