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 24 using namespace llvm; 25 26 EDInst::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 40 EDInst::~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 55 uint64_t EDInst::byteSize() { 56 return ByteSize; 57 } 58 59 int 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 71 int EDInst::getString(const char*& str) { 72 if (stringify()) 73 return -1; 74 75 str = String.c_str(); 76 77 return 0; 78 } 79 80 unsigned EDInst::instID() { 81 return Inst->getOpcode(); 82 } 83 84 bool EDInst::isBranch() { 85 if (ThisInstInfo) 86 return 87 ThisInstInfo->instructionType == kInstructionTypeBranch || 88 ThisInstInfo->instructionType == kInstructionTypeCall; 89 else 90 return false; 91 } 92 93 bool EDInst::isMove() { 94 if (ThisInstInfo) 95 return ThisInstInfo->instructionType == kInstructionTypeMove; 96 else 97 return false; 98 } 99 100 int 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 130 int EDInst::branchTargetID() { 131 if (parseOperands()) 132 return -1; 133 return BranchTarget; 134 } 135 136 int EDInst::moveSourceID() { 137 if (parseOperands()) 138 return -1; 139 return MoveSource; 140 } 141 142 int EDInst::moveTargetID() { 143 if (parseOperands()) 144 return -1; 145 return MoveTarget; 146 } 147 148 int EDInst::numOperands() { 149 if (parseOperands()) 150 return -1; 151 return Operands.size(); 152 } 153 154 int 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 165 int 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 182 int EDInst::numTokens() { 183 if (tokenize()) 184 return -1; 185 return Tokens.size(); 186 } 187 188 int 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__ 196 int 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