Merge branch 'master' of git.dyninst.org:/pub/dyninst into working
[dyninst.git] / dataflowAPI / src / ExpressionConversionVisitor.C
1 #include "ExpressionConversionVisitor.h"
2
3 #include "Register.h"
4 #include "Immediate.h"
5 #include "BinaryFunction.h"
6 #include "Dereference.h"
7
8 #include <list>
9
10 #include "../rose/SgAsmExpression.h"
11
12 using namespace Dyninst;
13 using namespace Dyninst::InstructionAPI;
14
15 //#include "../rose/x86InstructionSemantics.h"
16 //#include "../rose/powerpcInstructionSemantics.h"
17
18 using namespace Dyninst;
19 using namespace DataflowAPI;
20
21 void ExpressionConversionVisitor::visit(InstructionAPI::Immediate* immed) {
22   // no children
23   
24   const Result &value = immed->eval();
25   
26   // TODO rose doesn't distinguish signed/unsigned within the value itself,
27   // only at operations?
28   
29   // TODO rose doesn't handle large values (XMM?)
30   
31   // build different kind of rose value object based on type
32   switch (value.type) {
33   case s8:
34   case u8:
35     roseExpression = new SgAsmByteValueExpression(value.val.u8val);
36     break;
37   case s16:
38   case u16:
39     roseExpression = new SgAsmWordValueExpression(value.val.u16val);
40     break;
41   case s32:
42   case u32:
43     roseExpression = new SgAsmDoubleWordValueExpression(value.val.u32val);
44     break;
45   case s64:
46   case u64:
47     roseExpression = new SgAsmQuadWordValueExpression(value.val.u64val);
48     break;
49   case sp_float:
50     roseExpression = new SgAsmSingleFloatValueExpression(value.val.floatval);
51     break;
52   case dp_float:
53     roseExpression = new SgAsmDoubleFloatValueExpression(value.val.dblval);
54     break;
55   default:
56     roseExpression = NULL;
57     // error!
58   }
59   m_stack.push_front(roseExpression);
60 }
61
62
63 void ExpressionConversionVisitor::visit(RegisterAST* regast) {
64   // has no children
65   
66   m_stack.push_front(archSpecificRegisterProc(regast, addr));
67   roseExpression = m_stack.front();
68   return;
69 }
70
71 void ExpressionConversionVisitor::visit(Dereference* deref) {
72   // get child
73   assert(m_stack.size());
74   SgAsmExpression *toderef = m_stack.front();
75   m_stack.pop_front();
76   if(toderef == NULL) {
77     roseExpression = NULL;
78     return;
79   }
80   SgAsmType *type;
81
82   // TODO fix some mismatched types?
83   // pick correct type
84   switch (deref->eval().type)
85     {
86     case s8:
87     case u8:
88       type = new SgAsmTypeByte();
89       break;
90     case s16:
91     case u16:
92       type = new SgAsmTypeWord();
93       break;
94     case s32:
95     case u32:
96       type = new SgAsmTypeDoubleWord();
97       break;
98     case s64:
99     case u64:
100       type = new SgAsmTypeQuadWord();
101       break;
102     case sp_float:
103       type = new SgAsmTypeSingleFloat();
104       break;
105     case dp_float:
106       type = new SgAsmTypeDoubleFloat();
107       break;
108     default:
109       type = NULL;
110       // error
111     }
112
113
114   SgAsmExpression *segReg = makeSegRegExpr();
115   SgAsmMemoryReferenceExpression* result = new SgAsmMemoryReferenceExpression(toderef, segReg);
116   result->set_type(type);
117   roseExpression = result;
118 }
119
120 SgAsmExpression* ExpressionConversionVisitor::archSpecificRegisterProc(InstructionAPI::RegisterAST* regast, uint64_t addr)
121 {
122   MachRegister machReg = regast->getID();
123   if(machReg.isPC()) return NULL;
124
125   switch(arch) {
126   case Arch_x86: {
127     int regClass;
128     int regNum;
129     int regPos;
130    
131     MachRegister machReg = regast->getID();
132     if(machReg.isPC()) {
133       // ideally this would be symbolic
134       SgAsmExpression *constAddrExpr = new SgAsmDoubleWordValueExpression(addr);
135       return constAddrExpr;
136     } 
137     machReg.getROSERegister(regClass, regNum, regPos);
138     
139     return new SgAsmx86RegisterReferenceExpression((X86RegisterClass) regClass,
140                                                    regNum, 
141                                                    (X86PositionInRegister) regPos);
142     break;
143   }
144   case Arch_ppc32: {
145     int regClass;
146     int regNum;
147     int regGran = powerpc_condreggranularity_whole;
148
149     machReg.getROSERegister(regClass, regNum, regGran);
150
151     return new SgAsmPowerpcRegisterReferenceExpression((PowerpcRegisterClass) regClass, 
152                                                        regNum, 
153                                                        (PowerpcConditionRegisterAccessGranularity) regGran);
154     break;
155   }
156   default:
157     return NULL;
158     break;
159   }
160 }
161
162 SgAsmExpression* ExpressionConversionVisitor::makeSegRegExpr()
163 {
164   if (arch == Arch_x86) {
165     return new SgAsmx86RegisterReferenceExpression(x86_regclass_segment,
166                                                    x86_segreg_none, x86_regpos_all);
167   }
168   else {
169     return NULL;
170   }
171 }
172
173 /////////////// Visitor class /////////////////
174
175 void ExpressionConversionVisitor::visit(BinaryFunction* binfunc) {
176   assert(m_stack.size() >= 2);
177   SgAsmExpression *rhs = m_stack.front();
178   m_stack.pop_front();
179   SgAsmExpression *lhs = m_stack.front();
180   m_stack.pop_front();
181   // If the RHS didn't convert, that means it should disappear
182   // And we are just left with the LHS
183   if(!rhs && !lhs) {
184     roseExpression = NULL;
185   }
186   else if (!rhs) {
187     roseExpression = lhs;
188   }
189   else if(!lhs) {
190     roseExpression = rhs;
191   }
192   else {
193     // now build either add or multiply
194     if (binfunc->isAdd())
195       roseExpression = new SgAsmBinaryAdd(lhs, rhs);
196     else if (binfunc->isMultiply())
197       roseExpression = new SgAsmBinaryMultiply(lhs, rhs);
198     else roseExpression = NULL; // error
199   }
200   m_stack.push_front(roseExpression);
201 }