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"
21 #include "llvm/System/DataTypes.h"
24 EDToken::EDToken(StringRef str,
27 EDDisassembler &disassembler) :
28 Disassembler(disassembler),
38 void EDToken::makeLiteral(bool sign, uint64_t absoluteValue) {
41 LiteralAbsoluteValue = absoluteValue;
44 void EDToken::makeRegister(unsigned registerID) {
45 Type = kTokenRegister;
46 RegisterID = registerID;
49 void EDToken::setOperandID(int operandID) {
50 OperandID = operandID;
53 enum EDToken::tokenType EDToken::type() const {
57 uint64_t EDToken::localType() const {
61 StringRef EDToken::string() const {
65 int EDToken::operandID() const {
69 int EDToken::literalSign() const {
70 if (Type != kTokenLiteral)
72 return (LiteralSign ? 1 : 0);
75 int EDToken::literalAbsoluteValue(uint64_t &value) const {
76 if (Type != kTokenLiteral)
78 value = LiteralAbsoluteValue;
82 int EDToken::registerID(unsigned ®isterID) const {
83 if (Type != kTokenRegister)
85 registerID = RegisterID;
89 int EDToken::tokenize(std::vector<EDToken*> &tokens,
91 const char *operandOrder,
92 EDDisassembler &disassembler) {
93 SmallVector<MCParsedAsmOperand*, 5> parsedOperands;
94 SmallVector<AsmToken, 10> asmTokens;
96 if (disassembler.parseInst(parsedOperands, asmTokens, str))
99 SmallVectorImpl<MCParsedAsmOperand*>::iterator operandIterator;
100 unsigned int operandIndex;
101 SmallVectorImpl<AsmToken>::iterator tokenIterator;
103 operandIterator = parsedOperands.begin();
106 bool readOpcode = false;
108 const char *wsPointer = asmTokens.begin()->getLoc().getPointer();
110 for (tokenIterator = asmTokens.begin();
111 tokenIterator != asmTokens.end();
113 SMLoc tokenLoc = tokenIterator->getLoc();
115 const char *tokenPointer = tokenLoc.getPointer();
117 if (tokenPointer > wsPointer) {
118 unsigned long wsLength = tokenPointer - wsPointer;
120 EDToken *whitespaceToken = new EDToken(StringRef(wsPointer, wsLength),
121 EDToken::kTokenWhitespace,
125 tokens.push_back(whitespaceToken);
128 wsPointer = tokenPointer + tokenIterator->getString().size();
130 while (operandIterator != parsedOperands.end() &&
131 tokenLoc.getPointer() >
132 (*operandIterator)->getEndLoc().getPointer()) {
139 switch (tokenIterator->getKind()) {
140 case AsmToken::Identifier:
142 token = new EDToken(tokenIterator->getString(),
143 EDToken::kTokenOpcode,
144 (uint64_t)tokenIterator->getKind(),
149 // any identifier that isn't an opcode is mere punctuation; so we fall
152 token = new EDToken(tokenIterator->getString(),
153 EDToken::kTokenPunctuation,
154 (uint64_t)tokenIterator->getKind(),
157 case AsmToken::Integer:
159 token = new EDToken(tokenIterator->getString(),
160 EDToken::kTokenLiteral,
161 (uint64_t)tokenIterator->getKind(),
164 int64_t intVal = tokenIterator->getIntVal();
167 token->makeLiteral(true, -intVal);
169 token->makeLiteral(false, intVal);
172 case AsmToken::Register:
174 token = new EDToken(tokenIterator->getString(),
175 EDToken::kTokenLiteral,
176 (uint64_t)tokenIterator->getKind(),
179 token->makeRegister((unsigned)tokenIterator->getRegVal());
184 if (operandIterator != parsedOperands.end() &&
185 tokenLoc.getPointer() >=
186 (*operandIterator)->getStartLoc().getPointer()) {
187 /// operandIndex == 0 means the operand is the instruction (which the
188 /// AsmParser treats as an operand but edis does not). We therefore skip
189 /// operandIndex == 0 and subtract 1 from all other operand indices.
191 if (operandIndex > 0)
192 token->setOperandID(operandOrder[operandIndex - 1]);
195 tokens.push_back(token);
201 int EDToken::getString(const char*& buf) {
202 if (PermStr.length() == 0) {
205 buf = PermStr.c_str();