1 //===-- EDOperand.cpp - LLVM Enhanced Disassembler ------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the Enhanced Disassembly library's operand class. The
11 // operand is responsible for allowing evaluation given a particular register
14 //===----------------------------------------------------------------------===//
16 #include "EDOperand.h"
17 #include "EDDisassembler.h"
19 #include "llvm/MC/EDInstInfo.h"
20 #include "llvm/MC/MCInst.h"
23 EDOperand::EDOperand(const EDDisassembler &disassembler,
26 unsigned int &mcOpIndex) :
27 Disassembler(disassembler),
30 MCOpIndex(mcOpIndex) {
31 unsigned int numMCOperands = 0;
33 Triple::ArchType arch = Disassembler.TgtTriple.getArch();
35 if (arch == Triple::x86 ||
36 arch == Triple::x86_64) {
37 uint8_t operandType = inst.ThisInstInfo->operandTypes[opIndex];
39 switch (operandType) {
42 case kOperandTypeImmediate:
45 case kOperandTypeRegister:
48 case kOperandTypeX86Memory:
51 case kOperandTypeX86EffectiveAddress:
54 case kOperandTypeX86PCRelative:
59 else if (arch == Triple::arm ||
60 arch == Triple::thumb) {
61 uint8_t operandType = inst.ThisInstInfo->operandTypes[opIndex];
63 switch (operandType) {
65 case kOperandTypeARMRegisterList:
66 case kOperandTypeARMDPRRegisterList:
67 case kOperandTypeARMSPRRegisterList:
69 case kOperandTypeImmediate:
70 case kOperandTypeRegister:
71 case kOperandTypeARMBranchTarget:
72 case kOperandTypeARMSoImm:
73 case kOperandTypeARMRotImm:
74 case kOperandTypeThumb2SoImm:
75 case kOperandTypeARMSoImm2Part:
76 case kOperandTypeARMPredicate:
77 case kOperandTypeThumbITMask:
78 case kOperandTypeThumb2AddrModeImm8Offset:
79 case kOperandTypeARMTBAddrMode:
80 case kOperandTypeThumb2AddrModeImm8s4Offset:
81 case kOperandTypeARMAddrMode7:
82 case kOperandTypeThumb2AddrModeReg:
85 case kOperandTypeThumb2SoReg:
86 case kOperandTypeAddrModeImm12:
87 case kOperandTypeARMAddrMode2Offset:
88 case kOperandTypeARMAddrMode3Offset:
89 case kOperandTypeARMAddrMode4:
90 case kOperandTypeARMAddrMode5:
91 case kOperandTypeARMAddrModePC:
92 case kOperandTypeThumb2AddrModeImm8:
93 case kOperandTypeThumb2AddrModeImm12:
94 case kOperandTypeThumb2AddrModeImm8s4:
95 case kOperandTypeThumbAddrModeImmS1:
96 case kOperandTypeThumbAddrModeImmS2:
97 case kOperandTypeThumbAddrModeImmS4:
98 case kOperandTypeThumbAddrModeRR:
99 case kOperandTypeThumbAddrModeSP:
100 case kOperandTypeThumbAddrModePC:
103 case kOperandTypeARMSoReg:
104 case kOperandTypeLdStSOReg:
105 case kOperandTypeARMAddrMode2:
106 case kOperandTypeARMAddrMode3:
107 case kOperandTypeThumb2AddrModeSoReg:
108 case kOperandTypeThumbAddrModeRegS1:
109 case kOperandTypeThumbAddrModeRegS2:
110 case kOperandTypeThumbAddrModeRegS4:
111 case kOperandTypeARMAddrMode6Offset:
114 case kOperandTypeARMAddrMode6:
120 mcOpIndex += numMCOperands;
123 EDOperand::~EDOperand() {
126 int EDOperand::evaluate(uint64_t &result,
127 EDRegisterReaderCallback callback,
129 uint8_t operandType = Inst.ThisInstInfo->operandTypes[OpIndex];
131 Triple::ArchType arch = Disassembler.TgtTriple.getArch();
138 switch (operandType) {
141 case kOperandTypeImmediate:
142 result = Inst.Inst->getOperand(MCOpIndex).getImm();
144 case kOperandTypeRegister:
146 unsigned reg = Inst.Inst->getOperand(MCOpIndex).getReg();
147 return callback(&result, reg, arg);
149 case kOperandTypeX86PCRelative:
151 int64_t displacement = Inst.Inst->getOperand(MCOpIndex).getImm();
155 // TODO fix how we do this
157 if (callback(&ripVal, Disassembler.registerIDWithName("RIP"), arg))
160 result = ripVal + displacement;
163 case kOperandTypeX86Memory:
164 case kOperandTypeX86EffectiveAddress:
166 unsigned baseReg = Inst.Inst->getOperand(MCOpIndex).getReg();
167 uint64_t scaleAmount = Inst.Inst->getOperand(MCOpIndex+1).getImm();
168 unsigned indexReg = Inst.Inst->getOperand(MCOpIndex+2).getReg();
169 int64_t displacement = Inst.Inst->getOperand(MCOpIndex+3).getImm();
173 unsigned segmentReg = Inst.Inst->getOperand(MCOpIndex+4).getReg();
175 if (segmentReg != 0 && arch == Triple::x86_64) {
176 unsigned fsID = Disassembler.registerIDWithName("FS");
177 unsigned gsID = Disassembler.registerIDWithName("GS");
179 if (segmentReg == fsID ||
180 segmentReg == gsID) {
181 uint64_t segmentBase;
182 if (!callback(&segmentBase, segmentReg, arg))
189 if (callback(&baseVal, baseReg, arg))
196 if (callback(&indexVal, indexReg, arg))
198 addr += (scaleAmount * indexVal);
201 addr += displacement;
206 } // switch (operandType)
209 switch (operandType) {
212 case kOperandTypeImmediate:
213 if (!Inst.Inst->getOperand(MCOpIndex).isImm())
216 result = Inst.Inst->getOperand(MCOpIndex).getImm();
218 case kOperandTypeRegister:
220 if (!Inst.Inst->getOperand(MCOpIndex).isReg())
223 unsigned reg = Inst.Inst->getOperand(MCOpIndex).getReg();
224 return callback(&result, reg, arg);
226 case kOperandTypeARMBranchTarget:
228 if (!Inst.Inst->getOperand(MCOpIndex).isImm())
231 int64_t displacement = Inst.Inst->getOperand(MCOpIndex).getImm();
235 if (callback(&pcVal, Disassembler.registerIDWithName("PC"), arg))
238 result = pcVal + displacement;
245 int EDOperand::isRegister() {
246 return(Inst.ThisInstInfo->operandFlags[OpIndex] == kOperandTypeRegister);
249 unsigned EDOperand::regVal() {
250 return Inst.Inst->getOperand(MCOpIndex).getReg();
253 int EDOperand::isImmediate() {
254 return(Inst.ThisInstInfo->operandFlags[OpIndex] == kOperandTypeImmediate);
257 uint64_t EDOperand::immediateVal() {
258 return Inst.Inst->getOperand(MCOpIndex).getImm();
261 int EDOperand::isMemory() {
262 uint8_t operandType = Inst.ThisInstInfo->operandTypes[OpIndex];
264 switch (operandType) {
267 case kOperandTypeX86Memory:
268 case kOperandTypeX86PCRelative:
269 case kOperandTypeX86EffectiveAddress:
270 case kOperandTypeARMSoReg:
271 case kOperandTypeARMSoImm:
272 case kOperandTypeARMAddrMode2:
273 case kOperandTypeARMAddrMode2Offset:
274 case kOperandTypeARMAddrMode3:
275 case kOperandTypeARMAddrMode3Offset:
276 case kOperandTypeARMAddrMode4:
277 case kOperandTypeARMAddrMode5:
278 case kOperandTypeARMAddrMode6:
279 case kOperandTypeARMAddrMode7:
280 case kOperandTypeARMAddrModePC:
281 case kOperandTypeARMBranchTarget:
282 case kOperandTypeThumbAddrModeRegS1:
283 case kOperandTypeThumbAddrModeRegS2:
284 case kOperandTypeThumbAddrModeRegS4:
285 case kOperandTypeThumbAddrModeRR:
286 case kOperandTypeThumbAddrModeSP:
287 case kOperandTypeThumb2SoImm:
288 case kOperandTypeThumb2AddrModeImm8:
289 case kOperandTypeThumb2AddrModeImm8Offset:
290 case kOperandTypeThumb2AddrModeImm12:
291 case kOperandTypeThumb2AddrModeSoReg:
292 case kOperandTypeThumb2AddrModeImm8s4:
293 case kOperandTypeThumb2AddrModeReg:
300 struct RegisterReaderWrapper {
301 EDOperand::EDRegisterBlock_t regBlock;
305 static int readerWrapperCallback(uint64_t *value, unsigned regID, void *arg) {
306 RegisterReaderWrapper *wrapper = (RegisterReaderWrapper *)arg;
307 return wrapper->regBlock(value, regID);
310 int EDOperand::evaluate(uint64_t &result, EDRegisterBlock_t regBlock) {
311 RegisterReaderWrapper wrapper;
312 wrapper.regBlock = regBlock;
313 return evaluate(result, readerWrapperCallback, (void*)&wrapper);