1 //===-- EDToken.cpp - LLVM Enhanced Disassembler --------------------------===//
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 // 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.
14 //===----------------------------------------------------------------------===//
17 #include "EDDisassembler.h"
18 #include "llvm/MC/MCParser/MCAsmLexer.h"
19 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
20 #include "llvm/ADT/SmallVector.h"
23 EDToken::EDToken(StringRef str,
26 EDDisassembler &disassembler) :
27 Disassembler(disassembler),
37 void EDToken::makeLiteral(bool sign, uint64_t absoluteValue) {
40 LiteralAbsoluteValue = absoluteValue;
43 void EDToken::makeRegister(unsigned registerID) {
44 Type = kTokenRegister;
45 RegisterID = registerID;
48 void EDToken::setOperandID(int operandID) {
49 OperandID = operandID;
52 enum EDToken::tokenType EDToken::type() const {
56 uint64_t EDToken::localType() const {
60 StringRef EDToken::string() const {
64 int EDToken::operandID() const {
68 int EDToken::literalSign() const {
69 if (Type != kTokenLiteral)
71 return (LiteralSign ? 1 : 0);
74 int EDToken::literalAbsoluteValue(uint64_t &value) const {
75 if (Type != kTokenLiteral)
77 value = LiteralAbsoluteValue;
81 int EDToken::registerID(unsigned ®isterID) const {
82 if (Type != kTokenRegister)
84 registerID = RegisterID;
88 int EDToken::tokenize(std::vector<EDToken*> &tokens,
90 const signed char *operandOrder,
91 EDDisassembler &disassembler) {
92 SmallVector<MCParsedAsmOperand*, 5> parsedOperands;
93 SmallVector<AsmToken, 10> asmTokens;
95 if (disassembler.parseInst(parsedOperands, asmTokens, str))
97 for (unsigned i = 0, e = parsedOperands.size(); i != e; ++i)
98 delete parsedOperands[i];
102 SmallVectorImpl<MCParsedAsmOperand*>::iterator operandIterator;
103 unsigned int operandIndex;
104 SmallVectorImpl<AsmToken>::iterator tokenIterator;
106 operandIterator = parsedOperands.begin();
109 bool readOpcode = false;
111 const char *wsPointer = asmTokens.begin()->getLoc().getPointer();
113 for (tokenIterator = asmTokens.begin();
114 tokenIterator != asmTokens.end();
116 SMLoc tokenLoc = tokenIterator->getLoc();
118 const char *tokenPointer = tokenLoc.getPointer();
120 if (tokenPointer > wsPointer) {
121 unsigned long wsLength = tokenPointer - wsPointer;
123 EDToken *whitespaceToken = new EDToken(StringRef(wsPointer, wsLength),
124 EDToken::kTokenWhitespace,
128 tokens.push_back(whitespaceToken);
131 wsPointer = tokenPointer + tokenIterator->getString().size();
133 while (operandIterator != parsedOperands.end() &&
134 tokenLoc.getPointer() >
135 (*operandIterator)->getEndLoc().getPointer()) {
142 switch (tokenIterator->getKind()) {
143 case AsmToken::Identifier:
145 token = new EDToken(tokenIterator->getString(),
146 EDToken::kTokenOpcode,
147 (uint64_t)tokenIterator->getKind(),
152 // any identifier that isn't an opcode is mere punctuation; so we fall
155 token = new EDToken(tokenIterator->getString(),
156 EDToken::kTokenPunctuation,
157 (uint64_t)tokenIterator->getKind(),
160 case AsmToken::Integer:
162 token = new EDToken(tokenIterator->getString(),
163 EDToken::kTokenLiteral,
164 (uint64_t)tokenIterator->getKind(),
167 int64_t intVal = tokenIterator->getIntVal();
170 token->makeLiteral(true, -intVal);
172 token->makeLiteral(false, intVal);
175 case AsmToken::Register:
177 token = new EDToken(tokenIterator->getString(),
178 EDToken::kTokenLiteral,
179 (uint64_t)tokenIterator->getKind(),
182 token->makeRegister((unsigned)tokenIterator->getRegVal());
187 if (operandIterator != parsedOperands.end() &&
188 tokenLoc.getPointer() >=
189 (*operandIterator)->getStartLoc().getPointer()) {
190 /// 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.
194 if (operandIndex > 0)
195 token->setOperandID(operandOrder[operandIndex - 1]);
198 tokens.push_back(token);
201 // Free any parsed operands.
202 for (unsigned i = 0, e = parsedOperands.size(); i != e; ++i)
203 delete parsedOperands[i];
208 int EDToken::getString(const char*& buf) {
209 if (PermStr.length() == 0) {
212 buf = PermStr.c_str();