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