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