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 //===----------------------------------------------------------------------===//
16 #include "EDDisassembler.h"
19 #include "llvm/ADT/SmallVector.h"
20 #include "llvm/MC/MCParser/MCAsmLexer.h"
21 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
25 EDToken::EDToken(StringRef str,
28 EDDisassembler &disassembler) :
29 Disassembler(disassembler),
39 void EDToken::makeLiteral(bool sign, uint64_t absoluteValue) {
42 LiteralAbsoluteValue = absoluteValue;
45 void EDToken::makeRegister(unsigned registerID) {
46 Type = kTokenRegister;
47 RegisterID = registerID;
50 void EDToken::setOperandID(int operandID) {
51 OperandID = operandID;
54 enum EDToken::tokenType EDToken::type() const {
58 uint64_t EDToken::localType() const {
62 StringRef EDToken::string() const {
66 int EDToken::operandID() const {
70 int EDToken::literalSign() const {
71 if (Type != kTokenLiteral)
73 return (LiteralSign ? 1 : 0);
76 int EDToken::literalAbsoluteValue(uint64_t &value) const {
77 if (Type != kTokenLiteral)
79 value = LiteralAbsoluteValue;
83 int EDToken::registerID(unsigned ®isterID) const {
84 if (Type != kTokenRegister)
86 registerID = RegisterID;
90 int EDToken::tokenize(std::vector<EDToken*> &tokens,
92 const char *operandOrder,
93 EDDisassembler &disassembler) {
94 SmallVector<MCParsedAsmOperand*, 5> parsedOperands;
95 SmallVector<AsmToken, 10> asmTokens;
97 if (disassembler.parseInst(parsedOperands, asmTokens, str))
100 SmallVectorImpl<MCParsedAsmOperand*>::iterator operandIterator;
101 unsigned int operandIndex;
102 SmallVectorImpl<AsmToken>::iterator tokenIterator;
104 operandIterator = parsedOperands.begin();
107 bool readOpcode = false;
109 const char *wsPointer = asmTokens.begin()->getLoc().getPointer();
111 for (tokenIterator = asmTokens.begin();
112 tokenIterator != asmTokens.end();
114 SMLoc tokenLoc = tokenIterator->getLoc();
116 const char *tokenPointer = tokenLoc.getPointer();
118 if (tokenPointer > wsPointer) {
119 unsigned long wsLength = tokenPointer - wsPointer;
121 EDToken *whitespaceToken = new EDToken(StringRef(wsPointer, wsLength),
122 EDToken::kTokenWhitespace,
126 tokens.push_back(whitespaceToken);
129 wsPointer = tokenPointer + tokenIterator->getString().size();
131 while (operandIterator != parsedOperands.end() &&
132 tokenLoc.getPointer() >
133 (*operandIterator)->getEndLoc().getPointer()) {
140 switch (tokenIterator->getKind()) {
141 case AsmToken::Identifier:
143 token = new EDToken(tokenIterator->getString(),
144 EDToken::kTokenOpcode,
145 (uint64_t)tokenIterator->getKind(),
150 // any identifier that isn't an opcode is mere punctuation; so we fall
153 token = new EDToken(tokenIterator->getString(),
154 EDToken::kTokenPunctuation,
155 (uint64_t)tokenIterator->getKind(),
158 case AsmToken::Integer:
160 token = new EDToken(tokenIterator->getString(),
161 EDToken::kTokenLiteral,
162 (uint64_t)tokenIterator->getKind(),
165 int64_t intVal = tokenIterator->getIntVal();
168 token->makeLiteral(true, -intVal);
170 token->makeLiteral(false, intVal);
173 case AsmToken::Register:
175 token = new EDToken(tokenIterator->getString(),
176 EDToken::kTokenLiteral,
177 (uint64_t)tokenIterator->getKind(),
180 token->makeRegister((unsigned)tokenIterator->getRegVal());
185 if (operandIterator != parsedOperands.end() &&
186 tokenLoc.getPointer() >=
187 (*operandIterator)->getStartLoc().getPointer()) {
188 /// operandIndex == 0 means the operand is the instruction (which the
189 /// AsmParser treats as an operand but edis does not). We therefore skip
190 /// operandIndex == 0 and subtract 1 from all other operand indices.
192 if (operandIndex > 0)
193 token->setOperandID(operandOrder[operandIndex - 1]);
196 tokens.push_back(token);
202 int EDToken::getString(const char*& buf) {
203 if (PermStr.length() == 0) {
206 buf = PermStr.c_str();