00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "pent_include.h"
00022
00023 #include "Folder.h"
00024 #include "FuncNodes.h"
00025
00026 #include <deque>
00027 using std::deque;
00028 #include <set>
00029 using std::set;
00030
00031
00032
00033
00034
00035 void Unit::print_extern_unk(Console &o, const uint32 isize) const
00036 {
00037 o.Print("// External Functions:\n");
00038 FOR_CONST_SET(DCCallNode, externFuncs, i)
00039
00040 {
00041 indent(o, isize+1);
00042 (*i)->print_extern_unk(o, isize+1);
00043 o.Putchar('\n');
00044 }
00045 o.Print("// External Intrinsics:\n");
00046 {
00047 FOR_CONST_SET(DCCallNode, externIntrinsics, i)
00048
00049 {
00050 indent(o, isize+1);
00051 (*i)->print_extern_unk(o, isize+1);
00052 o.Putchar('\n');
00053 }
00054 }
00055 }
00056
00057 void Unit::print_unk(Console &o, const uint32 isize) const
00058 {
00059 FOR_CONST_DEQUE(DCFuncNode, functions, i)
00060 {
00061
00062 (*i)->print_unk_funcheader(o, isize);
00063
00064
00065 indent(o, isize);
00066 o.Print("{\n");
00067
00068
00069 (*i)->print_unk(o, isize+1);
00070
00071 indent(o, isize);
00072 o.Print("}\n");
00073 }
00074 }
00075
00076 void Unit::print_asm(Console &o) const
00077 {
00078 FOR_CONST_DEQUE(DCFuncNode, functions, i)
00079 {
00080 (*i)->print_asm(o);
00081 o.Putchar('\n');
00082 }
00083 }
00084
00085 void Unit::print_bin(ODequeDataSource &o) const
00086 {
00087 FOR_CONST_DEQUE(DCFuncNode, functions, i)
00088 {
00089 o.clear();
00090 (*i)->print_mac(con);
00091 (*i)->print_bin(o);
00092
00093 for(std::deque<char>::const_iterator i=o.buf().begin(); i!=o.buf().end(); ++i)
00094 con.Printf("%02X ", static_cast<uint8>(*i));
00095 con.Putchar('\n');
00096 }
00097 }
00098
00099
00100
00101
00102 #define UNITDEBUG
00103
00104 const bool DCUnit::fold(Node *n)
00105 {
00106 if(n==0)
00107 {
00108 print_asm(con);
00109 print_unk(con, 0);
00110 ODequeDataSource o;
00111
00112 print_extern_unk(con, 0);
00113
00114 con.Print("assert failed: n!=0\n");
00115 print_assert(0, this);
00116 exit(-1);
00117 }
00118
00119
00120
00121
00122
00123 while(elsestack.size()>0 && n->offset()==elsestack.back()->TargetOffset())
00124 {
00125 IfNode *last = elsestack.back();
00126 elsestack.pop_back();
00127 #ifdef UNITDEBUG
00128 con.Printf("Popping elsestack offset: %04X type %d at %04X\n", last->offset(), last->itype, n->offset());
00129 #endif
00130
00131
00132 assert(last->itype!=IfNode::I_IF && last->itype!=IfNode::I_ELSE_IF);
00133 if(elsestack.size()==0)
00134 assert(last->itype==IfNode::I_IF_ELSE || last->itype==IfNode::I_IF_ELSE_IF);
00135 if(elsestack.size()>0 && (last->itype==IfNode::I_ELSE_IF || last->itype==IfNode::I_ELSE_IF_ELSE))
00136 assert(last->TargetOffset()==elsestack.back()->TargetOffset());
00137 if(elsestack.size()>0)
00138 {
00139 assert(elsestack.back()->elsenode==0 || print_assert(elsestack.back(), this));
00140 elsestack.back()->elsenode=last;
00141 #ifdef UNITDEBUG
00142 print_assert(0, this);
00143 #endif
00144 }
00145
00146
00147 if(ifstack.size()>0 && last!=ifstack.back() && last->elsenode==0)
00148 {
00149 IfNode *newnode = new IfNode(IfNode::I_ELSE, last->TargetOffset());
00150
00151
00152
00153 newnode->fold_else(this, ifstack.back()->nodes());
00154 assert(last->elsenode==0 || print_assert(last->elsenode, this));
00155 assert(ifstack.back()->opcode()==0x51);
00156 ifstack.back()->nodes().push_back(newnode);
00157 }
00158 else if(nodes.size()>0 &&
00159 last!=nodes.back() &&
00160 last->elsenode==0
00161
00162
00163 )
00164
00165 {
00166 IfNode *newnode = new IfNode(IfNode::I_ELSE, last->TargetOffset());
00167 newnode->fold_else(this, nodes);
00168 assert(last->elsenode==0 || print_assert(last->elsenode, this));
00169 assert(nodes.back()->opcode()==0x51);
00170 nodes.push_back(newnode);
00171 }
00172 }
00173
00174 while(ifstack.size()>0 && n->offset()==ifstack.back()->TargetOffset())
00175 {
00176 IfNode *last = ifstack.back();
00177 ifstack.pop_back();
00178 #ifdef UNITDEBUG
00179 con.Printf("Popping ifstack offset: %04X type %d at %04X\n", last->offset(), last->itype, n->offset());
00180 #endif
00181
00182
00183 if(ifstack.size()==0)
00184 last->fold(this, nodes);
00185 else
00186 last->fold(this, ifstack.back()->nodes());
00187
00188
00189 if(last->itype!=IfNode::I_IF && last->itype!=IfNode::I_ELSE_IF)
00190 {
00191 #if 0
00192 con.Printf("Fnord: %04X\n", last->offset());
00193 print_assert(last, this);
00194 #endif
00195 if(elsestack.size()>0 && (elsestack.back()->itype==IfNode::I_IF_ELSE
00196 || elsestack.back()->itype==IfNode::I_ELSE_IF_ELSE))
00197 {
00198 elsestack.back()->elsenode=last;
00199 elsestack.pop_back();
00200 }
00201 elsestack.push_back(last);
00202 }
00203 }
00204
00205
00206 if(ifstack.size()==0)
00207 {
00208 if(n->fold(this, nodes))
00209 nodes.push_back(n);
00210 }
00211 else
00212 {
00213 if(n->fold(this, ifstack.back()->nodes()))
00214 ifstack.back()->nodes().push_back(n);
00215 }
00216
00217
00218 if(n->opcode()==0x51)
00219 setJump(static_cast<IfNode *>(n));
00220
00221
00222 if(n->opcode()==0x50)
00223 {
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 assert(elsestack.size()==0 || print_assert(n, this));
00236 DCFuncNode *func = new DCFuncNode();
00237 assert(ifstack.size()==0);
00238
00239 if(func->fold(this, nodes))
00240 nodes.push_back(func);
00241 }
00242
00243
00244 if(n->opcode()==0x7A)
00245 {
00246
00247 assert(nodes.back()->opcode()==0xFFFF);
00248 functions.push_back(static_cast<DCFuncNode *>(nodes.back()));
00249 nodes.pop_back();
00250 assert(nodes.size()==0);
00251 return true;
00252 }
00253 return false;
00254 }
00255
00256
00257
00258
00259
00260 void Folder::fold(Node *n)
00261 {
00262 if(n!=0)
00263 con.Printf("\t%04X:\t%02X\n", n->offset(), n->opcode());
00264 else
00265 con.Printf("WARNING: Got a null node, so something's not right, will terminate soon...\n");
00266
00267
00268 if(curr->fold(n))
00269 {
00270
00271
00272
00273
00274 }
00275 }
00276
00277 void Folder::print_unk(Console &o) const
00278 {
00279 con.Printf("Printing... %d\n", units.size());
00280 FOR_CONST_DEQUE(DCUnit, units, i)
00281 {
00282 (*i)->print_unk(o, 0);
00283 }
00284 }
00285
00286 void Folder::print_asm(Console &o) const
00287 {
00288 FOR_CONST_DEQUE(DCUnit, units, i)
00289 {
00290 (*i)->print_asm(o);
00291 }
00292 }
00293
00294 void Folder::print_bin(ODequeDataSource &o) const
00295 {
00296 FOR_CONST_DEQUE(DCUnit, units, i)
00297 {
00298 (*i)->print_bin(o);
00299 }
00300 }
00301
00302
00303
00304
00305
00306 bool print_assert_nodes(std::deque<Node *> &nodes, uint32 index)
00307 {
00308 indent(con, index);
00309 con.Printf("Nodes:");
00310 FOR_CONST_DEQUE(Node, nodes, i)
00311 {
00312 con.Putchar('\n');
00313 indent(con, index+1);
00314 con.Printf("%04X: %02X", (*i)->offset(), (*i)->opcode());
00315 }
00316 if(nodes.size()) con.Printf(" <-\n");
00317 con.Putchar('\n');
00318 return false;
00319 }
00320
00321 bool print_assert(const Node *n, const DCUnit *u)
00322 {
00323 if(n!=0)
00324 {
00325 con.Printf("\n========================================\n");
00326 con.Printf(" Error with opcode %02X at offset %04X.\n", n->opcode(), n->offset());
00327 con.Printf("========================================\n");
00328
00329 }
00330
00331 if(u!=0)
00332 {
00333 con.Printf("Num functions parsed: %d\n", u->functions.size());
00334
00335
00336
00337
00338 u->print_asm(con);
00339 u->print_unk(con, 0);
00340
00341 con.Printf("IfStack:");
00342 {
00343 FOR_CONST_DEQUE(IfNode, u->ifstack, i)
00344 {
00345 con.Printf("\n %04X: %02X -> %04X", (*i)->offset(), (*i)->opcode(), (*i)->TargetOffset());
00346 FOR_CONST_DEQUE(Node, (*i)->nodes(), j)
00347 {
00348 con.Printf("\n %04X: %02X", (*j)->offset(), (*j)->opcode());
00349 }
00350 }
00351 }
00352 if(u->ifstack.size()) con.Printf(" <-");
00353 con.Putchar('\n');
00354
00355 con.Printf("ElseStack:");
00356 {
00357 FOR_CONST_DEQUE(IfNode, u->elsestack, i)
00358 {
00359 con.Printf("\n %04X: %02X -> %04X", (*i)->offset(), (*i)->opcode(), (*i)->TargetOffset());
00360 FOR_CONST_DEQUE(Node, (*i)->nodes(), j)
00361 {
00362 con.Printf("\n %04X: %02X", (*j)->offset(), (*j)->opcode());
00363 }
00364 }
00365 }
00366 if(u->elsestack.size()) con.Printf(" <-");
00367 con.Putchar('\n');
00368
00369 con.Printf("Nodes:");
00370 {
00371 FOR_CONST_DEQUE(Node, u->nodes, i)
00372 {
00373 con.Printf("\n %04X: %02X", (*i)->offset(), (*i)->opcode());
00374 }
00375 }
00376 if(u->nodes.size()) con.Printf(" <-\n");
00377 con.Putchar('\n');
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387 }
00388
00389 return false;
00390 }
00391