1 //===-- 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 "EDToken.h" 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 using namespace llvm; 22 23 EDToken::EDToken(StringRef str, 24 enum tokenType type, 25 uint64_t localType, 26 EDDisassembler &disassembler) : 27 Disassembler(disassembler), 28 Str(str), 29 Type(type), 30 LocalType(localType), 31 OperandID(-1) { 32 } 33 34 EDToken::~EDToken() { 35 } 36 37 void EDToken::makeLiteral(bool sign, uint64_t absoluteValue) { 38 Type = kTokenLiteral; 39 LiteralSign = sign; 40 LiteralAbsoluteValue = absoluteValue; 41 } 42 43 void EDToken::makeRegister(unsigned registerID) { 44 Type = kTokenRegister; 45 RegisterID = registerID; 46 } 47 48 void EDToken::setOperandID(int operandID) { 49 OperandID = operandID; 50 } 51 52 enum EDToken::tokenType EDToken::type() const { 53 return Type; 54 } 55 56 uint64_t EDToken::localType() const { 57 return LocalType; 58 } 59 60 StringRef EDToken::string() const { 61 return Str; 62 } 63 64 int EDToken::operandID() const { 65 return OperandID; 66 } 67 68 int EDToken::literalSign() const { 69 if (Type != kTokenLiteral) 70 return -1; 71 return (LiteralSign ? 1 : 0); 72 } 73 74 int EDToken::literalAbsoluteValue(uint64_t &value) const { 75 if (Type != kTokenLiteral) 76 return -1; 77 value = LiteralAbsoluteValue; 78 return 0; 79 } 80 81 int EDToken::registerID(unsigned ®isterID) const { 82 if (Type != kTokenRegister) 83 return -1; 84 registerID = RegisterID; 85 return 0; 86 } 87 88 int EDToken::tokenize(std::vector<EDToken*> &tokens, 89 std::string &str, 90 const signed char *operandOrder, 91 EDDisassembler &disassembler) { 92 SmallVector<MCParsedAsmOperand*, 5> parsedOperands; 93 SmallVector<AsmToken, 10> asmTokens; 94 95 if (disassembler.parseInst(parsedOperands, asmTokens, str)) 96 { 97 for (unsigned i = 0, e = parsedOperands.size(); i != e; ++i) 98 delete parsedOperands[i]; 99 return -1; 100 } 101 102 SmallVectorImpl<MCParsedAsmOperand*>::iterator operandIterator; 103 unsigned int operandIndex; 104 SmallVectorImpl<AsmToken>::iterator tokenIterator; 105 106 operandIterator = parsedOperands.begin(); 107 operandIndex = 0; 108 109 bool readOpcode = false; 110 111 const char *wsPointer = asmTokens.begin()->getLoc().getPointer(); 112 113 for (tokenIterator = asmTokens.begin(); 114 tokenIterator != asmTokens.end(); 115 ++tokenIterator) { 116 SMLoc tokenLoc = tokenIterator->getLoc(); 117 118 const char *tokenPointer = tokenLoc.getPointer(); 119 120 if (tokenPointer > wsPointer) { 121 unsigned long wsLength = tokenPointer - wsPointer; 122 123 EDToken *whitespaceToken = new EDToken(StringRef(wsPointer, wsLength), 124 EDToken::kTokenWhitespace, 125 0, 126 disassembler); 127 128 tokens.push_back(whitespaceToken); 129 } 130 131 wsPointer = tokenPointer + tokenIterator->getString().size(); 132 133 while (operandIterator != parsedOperands.end() && 134 tokenLoc.getPointer() > 135 (*operandIterator)->getEndLoc().getPointer()) { 136 ++operandIterator; 137 ++operandIndex; 138 } 139 140 EDToken *token; 141 142 switch (tokenIterator->getKind()) { 143 case AsmToken::Identifier: 144 if (!readOpcode) { 145 token = new EDToken(tokenIterator->getString(), 146 EDToken::kTokenOpcode, 147 (uint64_t)tokenIterator->getKind(), 148 disassembler); 149 readOpcode = true; 150 break; 151 } 152 // any identifier that isn't an opcode is mere punctuation; so we fall 153 // through 154 default: 155 token = new EDToken(tokenIterator->getString(), 156 EDToken::kTokenPunctuation, 157 (uint64_t)tokenIterator->getKind(), 158 disassembler); 159 break; 160 case AsmToken::Integer: 161 { 162 token = new EDToken(tokenIterator->getString(), 163 EDToken::kTokenLiteral, 164 (uint64_t)tokenIterator->getKind(), 165 disassembler); 166 167 int64_t intVal = tokenIterator->getIntVal(); 168 169 if (intVal < 0) 170 token->makeLiteral(true, -intVal); 171 else 172 token->makeLiteral(false, intVal); 173 break; 174 } 175 case AsmToken::Register: 176 { 177 token = new EDToken(tokenIterator->getString(), 178 EDToken::kTokenLiteral, 179 (uint64_t)tokenIterator->getKind(), 180 disassembler); 181 182 token->makeRegister((unsigned)tokenIterator->getRegVal()); 183 break; 184 } 185 } 186 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. 193 194 if (operandIndex > 0) 195 token->setOperandID(operandOrder[operandIndex - 1]); 196 } 197 198 tokens.push_back(token); 199 } 200 201 // Free any parsed operands. 202 for (unsigned i = 0, e = parsedOperands.size(); i != e; ++i) 203 delete parsedOperands[i]; 204 205 return 0; 206 } 207 208 int EDToken::getString(const char*& buf) { 209 if (PermStr.length() == 0) { 210 PermStr = Str.str(); 211 } 212 buf = PermStr.c_str(); 213 return 0; 214 } 215