1894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===-EDInst.cpp - LLVM Enhanced Disassembler -----------------------------===// 2894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 3894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// The LLVM Compiler Infrastructure 4894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 5894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file is distributed under the University of Illinois Open Source 6894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// License. See LICENSE.TXT for details. 7894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 8894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 9894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 10894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file implements the Enhanced Disassembly library's instruction class. 11894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// The instruction is responsible for vending the string representation, 12894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// individual tokens, and operands for a single instruction. 13894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 14894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 15894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 16894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "EDInst.h" 17894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "EDDisassembler.h" 18894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "EDOperand.h" 19894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "EDToken.h" 20894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 21894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/MC/EDInstInfo.h" 22894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/MC/MCInst.h" 23894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 24894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanusing namespace llvm; 25894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 26894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanEDInst::EDInst(llvm::MCInst *inst, 27894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman uint64_t byteSize, 28894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EDDisassembler &disassembler, 29894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const llvm::EDInstInfo *info) : 30894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Disassembler(disassembler), 31894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Inst(inst), 32894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ThisInstInfo(info), 33894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ByteSize(byteSize), 34894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BranchTarget(-1), 35894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MoveSource(-1), 36894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MoveTarget(-1) { 37894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OperandOrder = ThisInstInfo->operandOrders[Disassembler.llvmSyntaxVariant()]; 38894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 39894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 40894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanEDInst::~EDInst() { 41894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned int index; 42894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned int numOperands = Operands.size(); 43894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 44894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (index = 0; index < numOperands; ++index) 45894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman delete Operands[index]; 46894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 47894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned int numTokens = Tokens.size(); 48894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 49894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (index = 0; index < numTokens; ++index) 50894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman delete Tokens[index]; 51894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 52894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman delete Inst; 53894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 54894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 55894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanuint64_t EDInst::byteSize() { 56894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return ByteSize; 57894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 58894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 59894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanint EDInst::stringify() { 60894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (StringifyResult.valid()) 61894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return StringifyResult.result(); 62894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 63894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Disassembler.printInst(String, *Inst)) 64894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return StringifyResult.setResult(-1); 6519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 6619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman String.push_back('\n'); 67894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 68894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return StringifyResult.setResult(0); 69894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 70894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 71894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanint EDInst::getString(const char*& str) { 72894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (stringify()) 73894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return -1; 74894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 75894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman str = String.c_str(); 76894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 77894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return 0; 78894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 79894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 80894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanunsigned EDInst::instID() { 81894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Inst->getOpcode(); 82894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 83894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 84894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool EDInst::isBranch() { 85894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ThisInstInfo) 86894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return 87894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ThisInstInfo->instructionType == kInstructionTypeBranch || 88894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ThisInstInfo->instructionType == kInstructionTypeCall; 89894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 90894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 91894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 92894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 93894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool EDInst::isMove() { 94894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ThisInstInfo) 95894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return ThisInstInfo->instructionType == kInstructionTypeMove; 96894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 97894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 98894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 99894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanint EDInst::parseOperands() { 101894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ParseResult.valid()) 102894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return ParseResult.result(); 103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 104894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!ThisInstInfo) 105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return ParseResult.setResult(-1); 106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned int opIndex; 108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned int mcOpIndex = 0; 109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (opIndex = 0; opIndex < ThisInstInfo->numOperands; ++opIndex) { 111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (isBranch() && 112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman (ThisInstInfo->operandFlags[opIndex] & kOperandFlagTarget)) { 113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BranchTarget = opIndex; 114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 115894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else if (isMove()) { 116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ThisInstInfo->operandFlags[opIndex] & kOperandFlagSource) 117894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MoveSource = opIndex; 118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else if (ThisInstInfo->operandFlags[opIndex] & kOperandFlagTarget) 119894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MoveTarget = opIndex; 120894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EDOperand *operand = new EDOperand(Disassembler, *this, opIndex, mcOpIndex); 123894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 124894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Operands.push_back(operand); 125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 126894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 127894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return ParseResult.setResult(0); 128894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 129894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 130894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanint EDInst::branchTargetID() { 131894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (parseOperands()) 132894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return -1; 133894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return BranchTarget; 134894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 135894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 136894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanint EDInst::moveSourceID() { 137894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (parseOperands()) 138894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return -1; 139894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return MoveSource; 140894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 141894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 142894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanint EDInst::moveTargetID() { 143894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (parseOperands()) 144894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return -1; 145894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return MoveTarget; 146894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 147894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 148894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanint EDInst::numOperands() { 149894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (parseOperands()) 150894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return -1; 151894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Operands.size(); 152894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 153894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 154894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanint EDInst::getOperand(EDOperand *&operand, unsigned int index) { 155894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (parseOperands()) 156894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return -1; 157894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 158894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (index >= Operands.size()) 159894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return -1; 160894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 161894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman operand = Operands[index]; 162894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return 0; 163894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 164894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 165894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanint EDInst::tokenize() { 166894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (TokenizeResult.valid()) 167894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return TokenizeResult.result(); 16819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 16919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (ThisInstInfo == NULL) 17019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return TokenizeResult.setResult(-1); 171894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 172894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (stringify()) 173894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return TokenizeResult.setResult(-1); 174894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 175894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return TokenizeResult.setResult(EDToken::tokenize(Tokens, 176894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman String, 177894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OperandOrder, 178894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Disassembler)); 179894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 180894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 181894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 182894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanint EDInst::numTokens() { 183894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (tokenize()) 184894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return -1; 185894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Tokens.size(); 186894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 187894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 188894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanint EDInst::getToken(EDToken *&token, unsigned int index) { 189894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (tokenize()) 190894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return -1; 191894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman token = Tokens[index]; 192894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return 0; 193894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 194894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 195894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#ifdef __BLOCKS__ 196894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanint EDInst::visitTokens(EDTokenVisitor_t visitor) { 197894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (tokenize()) 198894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return -1; 199894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 200894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman tokvec_t::iterator iter; 201894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 202894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (iter = Tokens.begin(); iter != Tokens.end(); ++iter) { 203894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int ret = visitor(*iter); 204894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ret == 1) 205894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return 0; 206894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ret != 0) 207894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return -1; 208894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 209894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 210894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return 0; 211894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 212894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif 213