1//===-EDInst.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 Disassembly library's instruction class. 11// The instruction is responsible for vending the string representation, 12// individual tokens, and operands for a single instruction. 13// 14//===----------------------------------------------------------------------===// 15 16#include "EDInst.h" 17#include "EDDisassembler.h" 18#include "EDOperand.h" 19#include "EDToken.h" 20 21#include "llvm/MC/EDInstInfo.h" 22#include "llvm/MC/MCInst.h" 23 24using namespace llvm; 25 26EDInst::EDInst(llvm::MCInst *inst, 27 uint64_t byteSize, 28 EDDisassembler &disassembler, 29 const llvm::EDInstInfo *info) : 30 Disassembler(disassembler), 31 Inst(inst), 32 ThisInstInfo(info), 33 ByteSize(byteSize), 34 BranchTarget(-1), 35 MoveSource(-1), 36 MoveTarget(-1) { 37 OperandOrder = ThisInstInfo->operandOrders[Disassembler.llvmSyntaxVariant()]; 38} 39 40EDInst::~EDInst() { 41 unsigned int index; 42 unsigned int numOperands = Operands.size(); 43 44 for (index = 0; index < numOperands; ++index) 45 delete Operands[index]; 46 47 unsigned int numTokens = Tokens.size(); 48 49 for (index = 0; index < numTokens; ++index) 50 delete Tokens[index]; 51 52 delete Inst; 53} 54 55uint64_t EDInst::byteSize() { 56 return ByteSize; 57} 58 59int EDInst::stringify() { 60 if (StringifyResult.valid()) 61 return StringifyResult.result(); 62 63 if (Disassembler.printInst(String, *Inst)) 64 return StringifyResult.setResult(-1); 65 66 String.push_back('\n'); 67 68 return StringifyResult.setResult(0); 69} 70 71int EDInst::getString(const char*& str) { 72 if (stringify()) 73 return -1; 74 75 str = String.c_str(); 76 77 return 0; 78} 79 80unsigned EDInst::instID() { 81 return Inst->getOpcode(); 82} 83 84bool EDInst::isBranch() { 85 if (ThisInstInfo) 86 return 87 ThisInstInfo->instructionType == kInstructionTypeBranch || 88 ThisInstInfo->instructionType == kInstructionTypeCall; 89 else 90 return false; 91} 92 93bool EDInst::isMove() { 94 if (ThisInstInfo) 95 return ThisInstInfo->instructionType == kInstructionTypeMove; 96 else 97 return false; 98} 99 100int EDInst::parseOperands() { 101 if (ParseResult.valid()) 102 return ParseResult.result(); 103 104 if (!ThisInstInfo) 105 return ParseResult.setResult(-1); 106 107 unsigned int opIndex; 108 unsigned int mcOpIndex = 0; 109 110 for (opIndex = 0; opIndex < ThisInstInfo->numOperands; ++opIndex) { 111 if (isBranch() && 112 (ThisInstInfo->operandFlags[opIndex] & kOperandFlagTarget)) { 113 BranchTarget = opIndex; 114 } 115 else if (isMove()) { 116 if (ThisInstInfo->operandFlags[opIndex] & kOperandFlagSource) 117 MoveSource = opIndex; 118 else if (ThisInstInfo->operandFlags[opIndex] & kOperandFlagTarget) 119 MoveTarget = opIndex; 120 } 121 122 EDOperand *operand = new EDOperand(Disassembler, *this, opIndex, mcOpIndex); 123 124 Operands.push_back(operand); 125 } 126 127 return ParseResult.setResult(0); 128} 129 130int EDInst::branchTargetID() { 131 if (parseOperands()) 132 return -1; 133 return BranchTarget; 134} 135 136int EDInst::moveSourceID() { 137 if (parseOperands()) 138 return -1; 139 return MoveSource; 140} 141 142int EDInst::moveTargetID() { 143 if (parseOperands()) 144 return -1; 145 return MoveTarget; 146} 147 148int EDInst::numOperands() { 149 if (parseOperands()) 150 return -1; 151 return Operands.size(); 152} 153 154int EDInst::getOperand(EDOperand *&operand, unsigned int index) { 155 if (parseOperands()) 156 return -1; 157 158 if (index >= Operands.size()) 159 return -1; 160 161 operand = Operands[index]; 162 return 0; 163} 164 165int EDInst::tokenize() { 166 if (TokenizeResult.valid()) 167 return TokenizeResult.result(); 168 169 if (ThisInstInfo == NULL) 170 return TokenizeResult.setResult(-1); 171 172 if (stringify()) 173 return TokenizeResult.setResult(-1); 174 175 return TokenizeResult.setResult(EDToken::tokenize(Tokens, 176 String, 177 OperandOrder, 178 Disassembler)); 179 180} 181 182int EDInst::numTokens() { 183 if (tokenize()) 184 return -1; 185 return Tokens.size(); 186} 187 188int EDInst::getToken(EDToken *&token, unsigned int index) { 189 if (tokenize()) 190 return -1; 191 token = Tokens[index]; 192 return 0; 193} 194 195#ifdef __BLOCKS__ 196int EDInst::visitTokens(EDTokenVisitor_t visitor) { 197 if (tokenize()) 198 return -1; 199 200 tokvec_t::iterator iter; 201 202 for (iter = Tokens.begin(); iter != Tokens.end(); ++iter) { 203 int ret = visitor(*iter); 204 if (ret == 1) 205 return 0; 206 if (ret != 0) 207 return -1; 208 } 209 210 return 0; 211} 212#endif 213