Use BranchProbability instead of floating points in IfConverter.
[llvm/stm8.git] / lib / MC / MCDisassembler / EDOperand.cpp
blob492bb08f336ad79b753fac5cdf28a51677ec3e14
1 //===-- EDOperand.cpp - LLVM Enhanced Disassembler ------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the Enhanced Disassembly library's operand class. The
11 // operand is responsible for allowing evaluation given a particular register
12 // context.
14 //===----------------------------------------------------------------------===//
16 #include "EDOperand.h"
17 #include "EDDisassembler.h"
18 #include "EDInst.h"
19 #include "llvm/MC/EDInstInfo.h"
20 #include "llvm/MC/MCInst.h"
21 using namespace llvm;
23 EDOperand::EDOperand(const EDDisassembler &disassembler,
24 const EDInst &inst,
25 unsigned int opIndex,
26 unsigned int &mcOpIndex) :
27 Disassembler(disassembler),
28 Inst(inst),
29 OpIndex(opIndex),
30 MCOpIndex(mcOpIndex) {
31 unsigned int numMCOperands = 0;
33 if (Disassembler.Key.Arch == Triple::x86 ||
34 Disassembler.Key.Arch == Triple::x86_64) {
35 uint8_t operandType = inst.ThisInstInfo->operandTypes[opIndex];
37 switch (operandType) {
38 default:
39 break;
40 case kOperandTypeImmediate:
41 numMCOperands = 1;
42 break;
43 case kOperandTypeRegister:
44 numMCOperands = 1;
45 break;
46 case kOperandTypeX86Memory:
47 numMCOperands = 5;
48 break;
49 case kOperandTypeX86EffectiveAddress:
50 numMCOperands = 4;
51 break;
52 case kOperandTypeX86PCRelative:
53 numMCOperands = 1;
54 break;
57 else if (Disassembler.Key.Arch == Triple::arm ||
58 Disassembler.Key.Arch == Triple::thumb) {
59 uint8_t operandType = inst.ThisInstInfo->operandTypes[opIndex];
61 switch (operandType) {
62 default:
63 case kOperandTypeARMRegisterList:
64 break;
65 case kOperandTypeImmediate:
66 case kOperandTypeRegister:
67 case kOperandTypeARMBranchTarget:
68 case kOperandTypeARMSoImm:
69 case kOperandTypeThumb2SoImm:
70 case kOperandTypeARMSoImm2Part:
71 case kOperandTypeARMPredicate:
72 case kOperandTypeThumbITMask:
73 case kOperandTypeThumb2AddrModeImm8Offset:
74 case kOperandTypeARMTBAddrMode:
75 case kOperandTypeThumb2AddrModeImm8s4Offset:
76 case kOperandTypeARMAddrMode7:
77 case kOperandTypeThumb2AddrModeReg:
78 numMCOperands = 1;
79 break;
80 case kOperandTypeThumb2SoReg:
81 case kOperandTypeARMAddrMode2Offset:
82 case kOperandTypeARMAddrMode3Offset:
83 case kOperandTypeARMAddrMode4:
84 case kOperandTypeARMAddrMode5:
85 case kOperandTypeARMAddrModePC:
86 case kOperandTypeThumb2AddrModeImm8:
87 case kOperandTypeThumb2AddrModeImm12:
88 case kOperandTypeThumb2AddrModeImm8s4:
89 case kOperandTypeThumbAddrModeRR:
90 case kOperandTypeThumbAddrModeSP:
91 numMCOperands = 2;
92 break;
93 case kOperandTypeARMSoReg:
94 case kOperandTypeARMAddrMode2:
95 case kOperandTypeARMAddrMode3:
96 case kOperandTypeThumb2AddrModeSoReg:
97 case kOperandTypeThumbAddrModeS1:
98 case kOperandTypeThumbAddrModeS2:
99 case kOperandTypeThumbAddrModeS4:
100 case kOperandTypeARMAddrMode6Offset:
101 numMCOperands = 3;
102 break;
103 case kOperandTypeARMAddrMode6:
104 numMCOperands = 4;
105 break;
109 mcOpIndex += numMCOperands;
112 EDOperand::~EDOperand() {
115 int EDOperand::evaluate(uint64_t &result,
116 EDRegisterReaderCallback callback,
117 void *arg) {
118 uint8_t operandType = Inst.ThisInstInfo->operandTypes[OpIndex];
120 switch (Disassembler.Key.Arch) {
121 default:
122 return -1;
123 case Triple::x86:
124 case Triple::x86_64:
125 switch (operandType) {
126 default:
127 return -1;
128 case kOperandTypeImmediate:
129 result = Inst.Inst->getOperand(MCOpIndex).getImm();
130 return 0;
131 case kOperandTypeRegister:
133 unsigned reg = Inst.Inst->getOperand(MCOpIndex).getReg();
134 return callback(&result, reg, arg);
136 case kOperandTypeX86PCRelative:
138 int64_t displacement = Inst.Inst->getOperand(MCOpIndex).getImm();
140 uint64_t ripVal;
142 // TODO fix how we do this
144 if (callback(&ripVal, Disassembler.registerIDWithName("RIP"), arg))
145 return -1;
147 result = ripVal + displacement;
148 return 0;
150 case kOperandTypeX86Memory:
151 case kOperandTypeX86EffectiveAddress:
153 unsigned baseReg = Inst.Inst->getOperand(MCOpIndex).getReg();
154 uint64_t scaleAmount = Inst.Inst->getOperand(MCOpIndex+1).getImm();
155 unsigned indexReg = Inst.Inst->getOperand(MCOpIndex+2).getReg();
156 int64_t displacement = Inst.Inst->getOperand(MCOpIndex+3).getImm();
158 uint64_t addr = 0;
160 unsigned segmentReg = Inst.Inst->getOperand(MCOpIndex+4).getReg();
162 if (segmentReg != 0 && Disassembler.Key.Arch == Triple::x86_64) {
163 unsigned fsID = Disassembler.registerIDWithName("FS");
164 unsigned gsID = Disassembler.registerIDWithName("GS");
166 if (segmentReg == fsID ||
167 segmentReg == gsID) {
168 uint64_t segmentBase;
169 if (!callback(&segmentBase, segmentReg, arg))
170 addr += segmentBase;
174 if (baseReg) {
175 uint64_t baseVal;
176 if (callback(&baseVal, baseReg, arg))
177 return -1;
178 addr += baseVal;
181 if (indexReg) {
182 uint64_t indexVal;
183 if (callback(&indexVal, indexReg, arg))
184 return -1;
185 addr += (scaleAmount * indexVal);
188 addr += displacement;
190 result = addr;
191 return 0;
193 } // switch (operandType)
194 break;
195 case Triple::arm:
196 case Triple::thumb:
197 switch (operandType) {
198 default:
199 return -1;
200 case kOperandTypeImmediate:
201 if (!Inst.Inst->getOperand(MCOpIndex).isImm())
202 return -1;
204 result = Inst.Inst->getOperand(MCOpIndex).getImm();
205 return 0;
206 case kOperandTypeRegister:
208 if (!Inst.Inst->getOperand(MCOpIndex).isReg())
209 return -1;
211 unsigned reg = Inst.Inst->getOperand(MCOpIndex).getReg();
212 return callback(&result, reg, arg);
214 case kOperandTypeARMBranchTarget:
216 if (!Inst.Inst->getOperand(MCOpIndex).isImm())
217 return -1;
219 int64_t displacement = Inst.Inst->getOperand(MCOpIndex).getImm();
221 uint64_t pcVal;
223 if (callback(&pcVal, Disassembler.registerIDWithName("PC"), arg))
224 return -1;
226 result = pcVal + displacement;
227 return 0;
230 break;
233 return -1;
236 int EDOperand::isRegister() {
237 return(Inst.ThisInstInfo->operandFlags[OpIndex] == kOperandTypeRegister);
240 unsigned EDOperand::regVal() {
241 return Inst.Inst->getOperand(MCOpIndex).getReg();
244 int EDOperand::isImmediate() {
245 return(Inst.ThisInstInfo->operandFlags[OpIndex] == kOperandTypeImmediate);
248 uint64_t EDOperand::immediateVal() {
249 return Inst.Inst->getOperand(MCOpIndex).getImm();
252 int EDOperand::isMemory() {
253 uint8_t operandType = Inst.ThisInstInfo->operandTypes[OpIndex];
255 switch (operandType) {
256 default:
257 return 0;
258 case kOperandTypeX86Memory:
259 case kOperandTypeX86PCRelative:
260 case kOperandTypeX86EffectiveAddress:
261 case kOperandTypeARMSoReg:
262 case kOperandTypeARMSoImm:
263 case kOperandTypeARMAddrMode2:
264 case kOperandTypeARMAddrMode2Offset:
265 case kOperandTypeARMAddrMode3:
266 case kOperandTypeARMAddrMode3Offset:
267 case kOperandTypeARMAddrMode4:
268 case kOperandTypeARMAddrMode5:
269 case kOperandTypeARMAddrMode6:
270 case kOperandTypeARMAddrMode7:
271 case kOperandTypeARMAddrModePC:
272 case kOperandTypeARMBranchTarget:
273 case kOperandTypeThumbAddrModeS1:
274 case kOperandTypeThumbAddrModeS2:
275 case kOperandTypeThumbAddrModeS4:
276 case kOperandTypeThumbAddrModeRR:
277 case kOperandTypeThumbAddrModeSP:
278 case kOperandTypeThumb2SoImm:
279 case kOperandTypeThumb2AddrModeImm8:
280 case kOperandTypeThumb2AddrModeImm8Offset:
281 case kOperandTypeThumb2AddrModeImm12:
282 case kOperandTypeThumb2AddrModeSoReg:
283 case kOperandTypeThumb2AddrModeImm8s4:
284 case kOperandTypeThumb2AddrModeReg:
285 return 1;
289 #ifdef __BLOCKS__
290 namespace {
291 struct RegisterReaderWrapper {
292 EDOperand::EDRegisterBlock_t regBlock;
296 static int readerWrapperCallback(uint64_t *value, unsigned regID, void *arg) {
297 RegisterReaderWrapper *wrapper = (RegisterReaderWrapper *)arg;
298 return wrapper->regBlock(value, regID);
301 int EDOperand::evaluate(uint64_t &result, EDRegisterBlock_t regBlock) {
302 RegisterReaderWrapper wrapper;
303 wrapper.regBlock = regBlock;
304 return evaluate(result, readerWrapperCallback, (void*)&wrapper);
306 #endif