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