1894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===-- EDOperand.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 operand class.  The
11894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// operand is responsible for allowing evaluation given a particular register
12894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// context.
13894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
14894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===//
15894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
16894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "EDOperand.h"
17894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "EDDisassembler.h"
18894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "EDInst.h"
19894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/MC/EDInstInfo.h"
20894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/MC/MCInst.h"
21894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanusing namespace llvm;
22894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
23894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanEDOperand::EDOperand(const EDDisassembler &disassembler,
24894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                     const EDInst &inst,
25894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                     unsigned int opIndex,
26894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                     unsigned int &mcOpIndex) :
27894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Disassembler(disassembler),
28894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Inst(inst),
29894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  OpIndex(opIndex),
30894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  MCOpIndex(mcOpIndex) {
31894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  unsigned int numMCOperands = 0;
32894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
33894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (Disassembler.Key.Arch == Triple::x86 ||
34894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      Disassembler.Key.Arch == Triple::x86_64) {
35894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    uint8_t operandType = inst.ThisInstInfo->operandTypes[opIndex];
36894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
37894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    switch (operandType) {
38894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    default:
39894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      break;
40894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case kOperandTypeImmediate:
41894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      numMCOperands = 1;
42894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      break;
43894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case kOperandTypeRegister:
44894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      numMCOperands = 1;
45894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      break;
46894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case kOperandTypeX86Memory:
47894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      numMCOperands = 5;
48894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      break;
49894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case kOperandTypeX86EffectiveAddress:
50894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      numMCOperands = 4;
51894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      break;
52894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case kOperandTypeX86PCRelative:
53894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      numMCOperands = 1;
54894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      break;
55894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
56894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
57894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  else if (Disassembler.Key.Arch == Triple::arm ||
58894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman           Disassembler.Key.Arch == Triple::thumb) {
59894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    uint8_t operandType = inst.ThisInstInfo->operandTypes[opIndex];
60894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
61894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    switch (operandType) {
62894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    default:
63894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case kOperandTypeARMRegisterList:
6419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case kOperandTypeARMDPRRegisterList:
6519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case kOperandTypeARMSPRRegisterList:
66894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      break;
67894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case kOperandTypeImmediate:
68894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case kOperandTypeRegister:
69894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case kOperandTypeARMBranchTarget:
70894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case kOperandTypeARMSoImm:
7119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case kOperandTypeARMRotImm:
72894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case kOperandTypeThumb2SoImm:
73894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case kOperandTypeARMSoImm2Part:
74894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case kOperandTypeARMPredicate:
75894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case kOperandTypeThumbITMask:
76894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case kOperandTypeThumb2AddrModeImm8Offset:
77894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case kOperandTypeARMTBAddrMode:
78894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case kOperandTypeThumb2AddrModeImm8s4Offset:
7919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case kOperandTypeARMAddrMode7:
8019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case kOperandTypeThumb2AddrModeReg:
81894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      numMCOperands = 1;
82894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      break;
83894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case kOperandTypeThumb2SoReg:
8419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case kOperandTypeAddrModeImm12:
85894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case kOperandTypeARMAddrMode2Offset:
86894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case kOperandTypeARMAddrMode3Offset:
87894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case kOperandTypeARMAddrMode4:
88894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case kOperandTypeARMAddrMode5:
89894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case kOperandTypeARMAddrModePC:
90894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case kOperandTypeThumb2AddrModeImm8:
91894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case kOperandTypeThumb2AddrModeImm12:
92894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case kOperandTypeThumb2AddrModeImm8s4:
9319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case kOperandTypeThumbAddrModeImmS1:
9419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case kOperandTypeThumbAddrModeImmS2:
9519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case kOperandTypeThumbAddrModeImmS4:
96894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case kOperandTypeThumbAddrModeRR:
97894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case kOperandTypeThumbAddrModeSP:
9819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case kOperandTypeThumbAddrModePC:
99894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      numMCOperands = 2;
100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      break;
101894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case kOperandTypeARMSoReg:
10219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case kOperandTypeLdStSOReg:
103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case kOperandTypeARMAddrMode2:
104894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case kOperandTypeARMAddrMode3:
105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case kOperandTypeThumb2AddrModeSoReg:
10619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case kOperandTypeThumbAddrModeRegS1:
10719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case kOperandTypeThumbAddrModeRegS2:
10819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case kOperandTypeThumbAddrModeRegS4:
109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case kOperandTypeARMAddrMode6Offset:
110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      numMCOperands = 3;
111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      break;
112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case kOperandTypeARMAddrMode6:
113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      numMCOperands = 4;
114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      break;
115894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
117894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  mcOpIndex += numMCOperands;
119894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
120894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanEDOperand::~EDOperand() {
122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
123894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
124894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanint EDOperand::evaluate(uint64_t &result,
125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                        EDRegisterReaderCallback callback,
126894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                        void *arg) {
127894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  uint8_t operandType = Inst.ThisInstInfo->operandTypes[OpIndex];
128894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
129894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  switch (Disassembler.Key.Arch) {
130894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  default:
131894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return -1;
132894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case Triple::x86:
133894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case Triple::x86_64:
134894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    switch (operandType) {
135894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    default:
136894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return -1;
137894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case kOperandTypeImmediate:
138894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      result = Inst.Inst->getOperand(MCOpIndex).getImm();
139894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return 0;
140894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case kOperandTypeRegister:
141894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    {
142894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      unsigned reg = Inst.Inst->getOperand(MCOpIndex).getReg();
143894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return callback(&result, reg, arg);
144894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
145894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case kOperandTypeX86PCRelative:
146894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    {
147894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      int64_t displacement = Inst.Inst->getOperand(MCOpIndex).getImm();
148894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
149894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      uint64_t ripVal;
150894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
151894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      // TODO fix how we do this
152894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
153894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if (callback(&ripVal, Disassembler.registerIDWithName("RIP"), arg))
154894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        return -1;
155894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
156894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      result = ripVal + displacement;
157894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return 0;
158894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
159894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case kOperandTypeX86Memory:
160894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case kOperandTypeX86EffectiveAddress:
161894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    {
162894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      unsigned baseReg = Inst.Inst->getOperand(MCOpIndex).getReg();
163894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      uint64_t scaleAmount = Inst.Inst->getOperand(MCOpIndex+1).getImm();
164894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      unsigned indexReg = Inst.Inst->getOperand(MCOpIndex+2).getReg();
165894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      int64_t displacement = Inst.Inst->getOperand(MCOpIndex+3).getImm();
16619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
167894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      uint64_t addr = 0;
168894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
16919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      unsigned segmentReg = Inst.Inst->getOperand(MCOpIndex+4).getReg();
17019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
17119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (segmentReg != 0 && Disassembler.Key.Arch == Triple::x86_64) {
17219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        unsigned fsID = Disassembler.registerIDWithName("FS");
17319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        unsigned gsID = Disassembler.registerIDWithName("GS");
17419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
17519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (segmentReg == fsID ||
17619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            segmentReg == gsID) {
17719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          uint64_t segmentBase;
17819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          if (!callback(&segmentBase, segmentReg, arg))
17919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            addr += segmentBase;
18019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        }
18119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
18219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
183894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if (baseReg) {
184894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        uint64_t baseVal;
185894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        if (callback(&baseVal, baseReg, arg))
186894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman          return -1;
187894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        addr += baseVal;
188894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      }
189894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
190894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if (indexReg) {
191894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        uint64_t indexVal;
192894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        if (callback(&indexVal, indexReg, arg))
193894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman          return -1;
194894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        addr += (scaleAmount * indexVal);
195894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      }
196894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
197894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      addr += displacement;
198894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
199894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      result = addr;
200894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return 0;
201894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
20219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    } // switch (operandType)
203894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    break;
204894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case Triple::arm:
205894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case Triple::thumb:
206894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    switch (operandType) {
207894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    default:
208894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return -1;
209894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case kOperandTypeImmediate:
21019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (!Inst.Inst->getOperand(MCOpIndex).isImm())
21119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return -1;
21219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
213894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      result = Inst.Inst->getOperand(MCOpIndex).getImm();
214894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return 0;
215894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case kOperandTypeRegister:
216894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    {
21719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (!Inst.Inst->getOperand(MCOpIndex).isReg())
21819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return -1;
21919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
220894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      unsigned reg = Inst.Inst->getOperand(MCOpIndex).getReg();
221894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return callback(&result, reg, arg);
222894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
223894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    case kOperandTypeARMBranchTarget:
224894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    {
22519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (!Inst.Inst->getOperand(MCOpIndex).isImm())
22619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return -1;
22719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
228894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      int64_t displacement = Inst.Inst->getOperand(MCOpIndex).getImm();
229894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
230894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      uint64_t pcVal;
231894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
232894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      if (callback(&pcVal, Disassembler.registerIDWithName("PC"), arg))
233894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman        return -1;
234894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
235894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      result = pcVal + displacement;
236894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      return 0;
237894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
238894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    }
23919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
240894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
241894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
242894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return -1;
243894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
244894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
245894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanint EDOperand::isRegister() {
246894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return(Inst.ThisInstInfo->operandFlags[OpIndex] == kOperandTypeRegister);
247894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
248894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
249894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanunsigned EDOperand::regVal() {
250894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return Inst.Inst->getOperand(MCOpIndex).getReg();
251894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
252894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
253894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanint EDOperand::isImmediate() {
254894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return(Inst.ThisInstInfo->operandFlags[OpIndex] == kOperandTypeImmediate);
255894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
256894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
257894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanuint64_t EDOperand::immediateVal() {
258894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return Inst.Inst->getOperand(MCOpIndex).getImm();
259894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
260894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
261894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanint EDOperand::isMemory() {
262894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  uint8_t operandType = Inst.ThisInstInfo->operandTypes[OpIndex];
263894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
264894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  switch (operandType) {
265894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  default:
266894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return 0;
267894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case kOperandTypeX86Memory:
268894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case kOperandTypeX86PCRelative:
269894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case kOperandTypeX86EffectiveAddress:
270894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case kOperandTypeARMSoReg:
271894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case kOperandTypeARMSoImm:
272894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case kOperandTypeARMAddrMode2:
273894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case kOperandTypeARMAddrMode2Offset:
274894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case kOperandTypeARMAddrMode3:
275894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case kOperandTypeARMAddrMode3Offset:
276894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case kOperandTypeARMAddrMode4:
277894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case kOperandTypeARMAddrMode5:
278894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case kOperandTypeARMAddrMode6:
27919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case kOperandTypeARMAddrMode7:
280894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case kOperandTypeARMAddrModePC:
281894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case kOperandTypeARMBranchTarget:
28219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case kOperandTypeThumbAddrModeRegS1:
28319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case kOperandTypeThumbAddrModeRegS2:
28419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case kOperandTypeThumbAddrModeRegS4:
285894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case kOperandTypeThumbAddrModeRR:
286894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case kOperandTypeThumbAddrModeSP:
287894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case kOperandTypeThumb2SoImm:
288894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case kOperandTypeThumb2AddrModeImm8:
289894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case kOperandTypeThumb2AddrModeImm8Offset:
290894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case kOperandTypeThumb2AddrModeImm12:
291894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case kOperandTypeThumb2AddrModeSoReg:
292894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  case kOperandTypeThumb2AddrModeImm8s4:
29319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case kOperandTypeThumb2AddrModeReg:
294894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return 1;
295894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
296894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
297894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
298894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#ifdef __BLOCKS__
29919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumannamespace {
30019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  struct RegisterReaderWrapper {
30119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    EDOperand::EDRegisterBlock_t regBlock;
30219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  };
30319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
304894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
30519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic int readerWrapperCallback(uint64_t *value, unsigned regID, void *arg) {
30619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  RegisterReaderWrapper *wrapper = (RegisterReaderWrapper *)arg;
307894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return wrapper->regBlock(value, regID);
308894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
309894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
31019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanint EDOperand::evaluate(uint64_t &result, EDRegisterBlock_t regBlock) {
31119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  RegisterReaderWrapper wrapper;
312894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  wrapper.regBlock = regBlock;
31319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return evaluate(result, readerWrapperCallback, (void*)&wrapper);
314894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
315894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif
316