Home | History | Annotate | Download | only in MCDisassembler
      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