Set default flags for .rodata.
[oota-llvm.git] / lib / MC / MCDisassembler / EDOperand.cpp
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.
13 //
14 //===----------------------------------------------------------------------===//
15
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;
22
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;
32     
33   if (Disassembler.Key.Arch == Triple::x86 ||
34       Disassembler.Key.Arch == Triple::x86_64) {
35     uint8_t operandType = inst.ThisInstInfo->operandTypes[opIndex];
36     
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;
55     }
56   }
57   else if (Disassembler.Key.Arch == Triple::arm ||
58            Disassembler.Key.Arch == Triple::thumb) {
59     uint8_t operandType = inst.ThisInstInfo->operandTypes[opIndex];
60     
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       numMCOperands = 1;
77       break;
78     case kOperandTypeThumb2SoReg:
79     case kOperandTypeARMAddrMode2Offset:
80     case kOperandTypeARMAddrMode3Offset:
81     case kOperandTypeARMAddrMode4:
82     case kOperandTypeARMAddrMode5:
83     case kOperandTypeARMAddrModePC:
84     case kOperandTypeThumb2AddrModeImm8:
85     case kOperandTypeThumb2AddrModeImm12:
86     case kOperandTypeThumb2AddrModeImm8s4:
87     case kOperandTypeThumbAddrModeRR:
88     case kOperandTypeThumbAddrModeSP:
89       numMCOperands = 2;
90       break;
91     case kOperandTypeARMSoReg:
92     case kOperandTypeARMAddrMode2:
93     case kOperandTypeARMAddrMode3:
94     case kOperandTypeThumb2AddrModeSoReg:
95     case kOperandTypeThumbAddrModeS1:
96     case kOperandTypeThumbAddrModeS2:
97     case kOperandTypeThumbAddrModeS4:
98     case kOperandTypeARMAddrMode6Offset:
99       numMCOperands = 3;
100       break;
101     case kOperandTypeARMAddrMode6:
102       numMCOperands = 4;
103       break;
104     }
105   }
106     
107   mcOpIndex += numMCOperands;
108 }
109
110 EDOperand::~EDOperand() {
111 }
112
113 int EDOperand::evaluate(uint64_t &result,
114                         EDRegisterReaderCallback callback,
115                         void *arg) {
116   uint8_t operandType = Inst.ThisInstInfo->operandTypes[OpIndex];
117   
118   switch (Disassembler.Key.Arch) {
119   default:
120     return -1;  
121   case Triple::x86:
122   case Triple::x86_64:    
123     switch (operandType) {
124     default:
125       return -1;
126     case kOperandTypeImmediate:
127       result = Inst.Inst->getOperand(MCOpIndex).getImm();
128       return 0;
129     case kOperandTypeRegister:
130     {
131       unsigned reg = Inst.Inst->getOperand(MCOpIndex).getReg();
132       return callback(&result, reg, arg);
133     }
134     case kOperandTypeX86PCRelative:
135     {
136       int64_t displacement = Inst.Inst->getOperand(MCOpIndex).getImm();
137         
138       uint64_t ripVal;
139         
140       // TODO fix how we do this
141         
142       if (callback(&ripVal, Disassembler.registerIDWithName("RIP"), arg))
143         return -1;
144         
145       result = ripVal + displacement;
146       return 0;
147     }
148     case kOperandTypeX86Memory:
149     case kOperandTypeX86EffectiveAddress:  
150     {
151       unsigned baseReg = Inst.Inst->getOperand(MCOpIndex).getReg();
152       uint64_t scaleAmount = Inst.Inst->getOperand(MCOpIndex+1).getImm();
153       unsigned indexReg = Inst.Inst->getOperand(MCOpIndex+2).getReg();
154       int64_t displacement = Inst.Inst->getOperand(MCOpIndex+3).getImm();
155       //unsigned segmentReg = Inst.Inst->getOperand(MCOpIndex+4).getReg();
156       
157       uint64_t addr = 0;
158         
159       if (baseReg) {
160         uint64_t baseVal;
161         if (callback(&baseVal, baseReg, arg))
162           return -1;
163         addr += baseVal;
164       }
165         
166       if (indexReg) {
167         uint64_t indexVal;
168         if (callback(&indexVal, indexReg, arg))
169           return -1;
170         addr += (scaleAmount * indexVal);
171       }
172        
173       addr += displacement;
174        
175       result = addr;
176       return 0;
177     }
178     }
179     break;
180   case Triple::arm:
181   case Triple::thumb:
182     switch (operandType) {
183     default:
184       return -1;
185     case kOperandTypeImmediate:
186       result = Inst.Inst->getOperand(MCOpIndex).getImm();
187       return 0;
188     case kOperandTypeRegister:
189     {
190       unsigned reg = Inst.Inst->getOperand(MCOpIndex).getReg();
191       return callback(&result, reg, arg);
192     }
193     case kOperandTypeARMBranchTarget:
194     {
195       int64_t displacement = Inst.Inst->getOperand(MCOpIndex).getImm();
196       
197       uint64_t pcVal;
198       
199       if (callback(&pcVal, Disassembler.registerIDWithName("PC"), arg))
200         return -1;
201       
202       result = pcVal + displacement;
203       return 0;
204     }
205     }
206   }
207   
208   return -1;
209 }
210
211 int EDOperand::isRegister() {
212   return(Inst.ThisInstInfo->operandFlags[OpIndex] == kOperandTypeRegister);
213 }
214
215 unsigned EDOperand::regVal() {
216   return Inst.Inst->getOperand(MCOpIndex).getReg(); 
217 }
218
219 int EDOperand::isImmediate() {
220   return(Inst.ThisInstInfo->operandFlags[OpIndex] == kOperandTypeImmediate);
221 }
222
223 uint64_t EDOperand::immediateVal() {
224   return Inst.Inst->getOperand(MCOpIndex).getImm();
225 }
226
227 int EDOperand::isMemory() {
228   uint8_t operandType = Inst.ThisInstInfo->operandTypes[OpIndex];
229     
230   switch (operandType) {
231   default:
232     return 0;
233   case kOperandTypeX86Memory:
234   case kOperandTypeX86PCRelative:
235   case kOperandTypeX86EffectiveAddress:
236   case kOperandTypeARMSoReg:
237   case kOperandTypeARMSoImm:
238   case kOperandTypeARMAddrMode2:
239   case kOperandTypeARMAddrMode2Offset:
240   case kOperandTypeARMAddrMode3:
241   case kOperandTypeARMAddrMode3Offset:
242   case kOperandTypeARMAddrMode4:
243   case kOperandTypeARMAddrMode5:
244   case kOperandTypeARMAddrMode6:
245   case kOperandTypeARMAddrModePC:
246   case kOperandTypeARMBranchTarget:
247   case kOperandTypeThumbAddrModeS1:
248   case kOperandTypeThumbAddrModeS2:
249   case kOperandTypeThumbAddrModeS4:
250   case kOperandTypeThumbAddrModeRR:
251   case kOperandTypeThumbAddrModeSP:
252   case kOperandTypeThumb2SoImm:
253   case kOperandTypeThumb2AddrModeImm8:
254   case kOperandTypeThumb2AddrModeImm8Offset:
255   case kOperandTypeThumb2AddrModeImm12:
256   case kOperandTypeThumb2AddrModeSoReg:
257   case kOperandTypeThumb2AddrModeImm8s4:
258     return 1;
259   }
260 }
261
262 #ifdef __BLOCKS__
263 namespace {
264   struct RegisterReaderWrapper {
265     EDOperand::EDRegisterBlock_t regBlock;
266   };
267 }
268
269 static int readerWrapperCallback(uint64_t *value, unsigned regID, void *arg) {
270   RegisterReaderWrapper *wrapper = (RegisterReaderWrapper *)arg;
271   return wrapper->regBlock(value, regID);
272 }
273
274 int EDOperand::evaluate(uint64_t &result, EDRegisterBlock_t regBlock) {
275   RegisterReaderWrapper wrapper;
276   wrapper.regBlock = regBlock;
277   return evaluate(result, readerWrapperCallback, (void*)&wrapper);
278 }
279 #endif