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 "CallNodes.h"
00024 #include "Folder.h"
00025 #include "VarNodes.h"
00026
00027
00028
00029 void AddSpToDCCallNode(DCCallPostfixNode *cpn, Node *node)
00030 {
00031 DCCallNode *cn = static_cast<DCCallNode *>(node);
00032 cn->setAddSP(cpn);
00033 }
00034 void PushRetValToDCCallNode(DCCallPostfixNode *cpn, Node *node)
00035 {
00036 DCCallNode *cn = static_cast<DCCallNode *>(node);
00037 cn->setRetVal(cpn);
00038 }
00039 void AddFreeToDCCallNode(DCCallPostfixNode *cpn, Node *node)
00040 {
00041 DCCallNode *cn = static_cast<DCCallNode *>(node);
00042 cn->addFree(cpn);
00043 }
00044
00045
00046
00047
00048
00049 bool DCCallPostfixNode::fold(DCUnit *unit, std::deque<Node *> &nodes)
00050 {
00051 if(acceptOp(nodes.back()->opcode(), 0x0F, 0x11, 0x57))
00052 {
00053 switch(ptype)
00054 {
00055 case PUSH_RETVAL: PushRetValToDCCallNode(this, nodes.back()); break;
00056 case FREESTR: AddFreeToDCCallNode(this, nodes.back()); break;
00057 case ADDSP: AddSpToDCCallNode(this, nodes.back()); break;
00058 default: assert(print_assert(this));
00059 }
00060 nodes.back()->fold(unit, nodes);
00061 }
00062 return false;
00063 }
00064
00065 void DCCallPostfixNode::print_unk(Console &o, const uint32 , const bool comment) const
00066 {
00067 if(!comment) return;
00068
00069 switch(ptype)
00070 {
00071 case PUSH_RETVAL:
00072 assert(rtype().type()!=Type::T_INVALID);
00073 switch(rtype().type())
00074 {
00075 case Type::T_BYTE: o.Printf("push_byte_retval_NOPRINT()"); break;
00076 case Type::T_WORD: o.Printf("push_retval_NOPRINT()"); break;
00077 default: assert(print_assert(this));
00078 }
00079 break;
00080 case FREESTR:
00081 assert(rtype().type()==Type::T_INVALID);
00082 o.Printf("free_str_NOPRINT(%s)", suc::print_sp(sp));
00083 break;
00084 case ADDSP:
00085 assert(rtype().type()==Type::T_INVALID);
00086 o.Printf("addsp_NOPRINT(0x%s%02X)", sp>0x7F?"-":"", sp>0x7F?0x100-sp:sp);
00087 break;
00088 default: assert(print_assert(this));
00089 }
00090 }
00091
00092 void DCCallPostfixNode::print_asm(Console &o) const
00093 {
00094 Node::print_asm(o);
00095 switch(ptype)
00096 {
00097 case PUSH_RETVAL:
00098 assert(rtype().type()!=Type::T_INVALID);
00099 switch(rtype().type())
00100 {
00101 case Type::T_BYTE: o.Printf("push byte\tretval"); break;
00102 case Type::T_WORD: o.Printf("push\t\tretval"); break;
00103 default: assert(false);
00104 }
00105 break;
00106 case FREESTR:
00107 assert(rtype().type()==Type::T_INVALID);
00108 o.Printf("free string\t%s", suc::print_sp(sp));
00109 break;
00110 case ADDSP:
00111 assert(rtype().type()==Type::T_INVALID);
00112 o.Printf("add sp\t\t%s%02Xh", sp>0x7F?"-":"", sp>0x7F?0x100-sp:sp);
00113 break;
00114 default: assert(print_assert(this));
00115 }
00116 }
00117
00118 void DCCallPostfixNode::print_bin(ODequeDataSource &o) const
00119 {
00120 switch(ptype)
00121 {
00122 case PUSH_RETVAL:
00123 assert(rtype().type()!=Type::T_INVALID);
00124 switch(rtype().type())
00125 {
00126 case Type::T_BYTE: o.write1(0x5D); break;
00127 case Type::T_WORD: o.write1(0x5E); break;
00128 default: assert(print_assert(this));
00129 }
00130 break;
00131 case FREESTR:
00132 assert(rtype().type()==Type::T_INVALID);
00133 o.write1(0x65);
00134 o.write1(sp);
00135 break;
00136 case ADDSP:
00137 assert(rtype().type()==Type::T_INVALID);
00138 o.write1(0x6E);
00139 o.write1(sp);
00140 break;
00141 default: assert(print_assert(this));
00142 }
00143 }
00144
00145
00146
00147
00148
00149 void DCCallMutatorNode::print_unk(Console &o, const uint32 isize, const bool comment) const
00150 {
00151 if(!comment && mtype!=PROCESS_EXCLUDE) return;
00152
00153 switch(mtype)
00154 {
00155 case PUSH_INDIRECT:
00156 assert(rtype().type()!=Type::T_INVALID);
00157 o.Printf("push_indirect_NOPRINT(0x%02X, ", numBytes);
00158 lnode->print_unk(o, isize);
00159 o.Putchar(')');
00160 break;
00161 case SET_INFO:
00162 assert(rtype().type()==Type::T_INVALID);
00163 o.Printf("setinfo_NOPRINT(");
00164 lnode->print_unk(o, isize);
00165 o.Printf(", ");
00166 rnode->print_unk(o, isize);
00167 o.Putchar(')');
00168 break;
00169 case PROCESS_EXCLUDE:
00170 assert(rtype().type()==Type::T_INVALID);
00171 o.Printf("process_exclude()");
00172 break;
00173 default: assert(print_assert(this));
00174 }
00175 }
00176
00177 void DCCallMutatorNode::print_asm(Console &o) const
00178 {
00179 switch(mtype)
00180 {
00181 case PUSH_INDIRECT:
00182 assert(rtype().type()!=Type::T_INVALID);
00183 lnode->print_asm(o);
00184 o.Putchar('\n');
00185 Node::print_asm(o);
00186 o.Printf("push indirect\t%02Xh bytes", numBytes);
00187 break;
00188 case SET_INFO:
00189 assert(rtype().type()==Type::T_INVALID);
00190 lnode->print_asm(o);
00191 o.Putchar('\n');
00192 rnode->print_asm(o);
00193 o.Putchar('\n');
00194 Node::print_asm(o);
00195 o.Printf("set info");
00196 break;
00197 case PROCESS_EXCLUDE:
00198 assert(rtype().type()==Type::T_INVALID);
00199 Node::print_asm(o);
00200 o.Printf("process exclude");
00201 break;
00202 default: assert(print_assert(this));
00203 }
00204 }
00205
00206 void DCCallMutatorNode::print_bin(ODequeDataSource &o) const
00207 {
00208 switch(mtype)
00209 {
00210 case PUSH_INDIRECT:
00211 assert(rtype().type()!=Type::T_INVALID);
00212 lnode->print_bin(o);
00213 o.write1(0x4C);
00214 o.write1(numBytes);
00215 break;
00216 case SET_INFO:
00217 assert(rtype().type()==Type::T_INVALID);
00218
00219 lnode->print_bin(o);
00220 rnode->print_bin(o);
00221 o.write1(0x77);
00222 break;
00223 case PROCESS_EXCLUDE:
00224 assert(rtype().type()==Type::T_INVALID);
00225
00226 o.write1(0x78);
00227 break;
00228 default: assert(print_assert(this));
00229 }
00230 }
00231
00232 bool DCCallMutatorNode::fold(DCUnit * , std::deque<Node *> &nodes)
00233 {
00234 switch(mtype)
00235 {
00236 case PUSH_INDIRECT:
00237
00238
00239 assert(nodes.back()->rtype()==Type::T_DWORD);
00240 grab_l(nodes);
00241 break;
00242 case SET_INFO:
00243 assert(nodes.back()->rtype()==Type::T_WORD);
00244 grab_r(nodes);
00245 assert(nodes.back()->rtype()==Type::T_WORD);
00246 grab_l(nodes);
00247 break;
00248 case PROCESS_EXCLUDE:
00249 break;
00250 default: assert(print_assert(this));
00251 }
00252 return true;
00253 };
00254
00255
00256
00257
00258
00259
00260 bool DCCallNode::fold(DCUnit *unit, std::deque<Node *> &nodes)
00261 {
00262
00263 switch(ctype)
00264 {
00265 case CALL: unit->registerExternFunc(this); break;
00266 case CALLI: unit->registerExternIntrinsic(this); break;
00267 case SPAWN: unit->registerExternFunc(this); break;
00268 default: assert(print_assert(this, unit));
00269 }
00270
00271
00272
00273
00274
00275 if(addSP==0 && retVal==0)
00276 return true;
00277
00278 else if((addSP!=0 && retVal==0)
00279 || (ctype==SPAWN && (thispsize>0 && thisP==0)))
00280 {
00281 con.Printf("Op %02X %04X\n", nodes.back()->opcode(), nodes.back()->offset());
00282
00283 assert(acceptOp(nodes.back()->opcode(), 0x0F, 0x11, 0x57));
00284 Node *us=nodes.back();
00285 nodes.pop_back();
00286
00287
00288
00289 if(thispsize>0 && ctype==SPAWN)
00290 {
00291 thisP = grab(nodes);
00292
00293
00294
00295 assert(thisP!=0 && thisP->rtype()==Type::T_DWORD);
00296 }
00297
00298
00299
00300 if(ctype==SPAWN) {
00301 if(spsize>0)
00302 grab_p(nodes, std::abs(static_cast<sint32>(addSP->size())));
00303 } else
00304 grab_p(nodes, std::abs(static_cast<sint32>(addSP->size())));
00305
00306
00307 nodes.push_back(us);
00308 }
00309
00310 else if(ctype==CALLI && spsize==0 && addSP==0 && retVal!=0)
00311 rtype(retVal->rtype());
00312 else if(addSP!=0 && retVal!=0)
00313 rtype(retVal->rtype());
00314 else if(nodes.size()>0 && acceptOp(nodes.back()->opcode(), 0x65))
00315 { }
00316 else if(retVal!=0 && nodes.size()>0 && acceptOp(nodes.back()->opcode(), 0x57))
00317 {
00318
00319
00320 }
00321 else
00322 {
00323 con.Printf("Fnord: %d\n", freenodes.size());
00324 assert(print_assert(this, unit));
00325 }
00326
00327
00328
00329 fold_linenum(nodes);
00330
00331 return false;
00332 }
00333
00334 void DCCallNode::print_extern_unk(Console &o, const uint32 ) const
00335 {
00336 switch(ctype)
00337 {
00338 case CALLI:
00339 {
00340 if(rtype().type()!=Type::T_INVALID)
00341 {
00342 o.Print(rtype().name()); o.Putchar('\t');
00343 }
00344 o.Printf("Intrinsic%04X(", intrinsic);
00345 for(std::deque<Node *>::const_reverse_iterator i=pnode.rbegin(); i!=pnode.rend(); ++i)
00346 {
00347 if(i!=pnode.rbegin()) o.Print(", ");
00348 o.Print((*i)->rtype().name());
00349 }
00350 o.Print(");");
00351 break;
00352 }
00353 case CALL:
00354 {
00355 if(rtype().type()!=Type::T_INVALID)
00356 {
00357 o.Print(rtype().name()); o.Putchar('\t');
00358 }
00359 o.Printf("class_%04X_function_%04X(", uclass, targetOffset);
00360 for(std::deque<Node *>::const_reverse_iterator i=pnode.rbegin(); i!=pnode.rend(); ++i)
00361 {
00362 if(i!=pnode.rbegin()) o.Print(", ");
00363 o.Print((*i)->rtype().name());
00364 }
00365 o.Print(");");
00366 break;
00367 }
00368 case SPAWN:
00369 {
00370 o.Print("spawn ");
00371 if(rtype().type()!=Type::T_INVALID)
00372 {
00373 o.Print(rtype().name()); o.Putchar('\t');
00374 }
00375 if(thisP!=0) o.Print(thisP->rtype().name());
00376 o.Printf("->class_%04X_function_%04X(", uclass, targetOffset);
00377 for(std::deque<Node *>::const_reverse_iterator i=pnode.rbegin(); i!=pnode.rend(); ++i)
00378 {
00379 if(i!=pnode.rbegin()) o.Print(", ");
00380 o.Print((*i)->rtype().name());
00381 }
00382 o.Print(");");
00383 break;
00384 }
00385 default: assert(print_assert(this));
00386 }
00387 }
00388
00389 void DCCallNode::print_unk(Console &o, const uint32 isize) const
00390 {
00391 print_linenum_unk(o, isize);
00392 switch(ctype)
00393 {
00394 case CALLI:
00395 {
00396 #if 0
00397 if(rtype().type()!=Type::T_VOID)
00398 {
00399 rtype().print_unk(o); o.Putchar(' ');
00400 }
00401 #endif
00402 o.Printf("Intrinsic%04X(", intrinsic);
00403 for(std::deque<Node *>::const_reverse_iterator i=pnode.rbegin(); i!=pnode.rend(); ++i)
00404 {
00405 if(i!=pnode.rbegin()) o.Print(", ");
00406 (*i)->print_unk(o, isize);
00407 }
00408 o.Putchar(')');
00409 break;
00410 }
00411 case CALL:
00412 {
00413 #if 0
00414 if(rtype().type()!=Type::T_VOID)
00415 {
00416 rtype().print_unk(o); o.Putchar(' ');
00417 }
00418 #endif
00419 o.Printf("class_%04X_function_%04X(", uclass, targetOffset);
00420 for(std::deque<Node *>::const_reverse_iterator i=pnode.rbegin(); i!=pnode.rend(); ++i)
00421 {
00422 if(i!=pnode.rbegin()) o.Print(", ");
00423 (*i)->print_unk(o, isize);
00424 }
00425 o.Putchar(')');
00426 break;
00427 }
00428 case SPAWN:
00429 {
00430 o.Print("spawn ");
00431 #if 0
00432 if(rtype().type()!=Type::T_VOID)
00433 {
00434 rtype().print_unk(o); o.Putchar(' ');
00435 }
00436 #endif
00437 assert(thispsize>0 || thisP!=0 || print_assert(this));
00438 if(thispsize)
00439 thisP->print_unk(o, isize);
00440 o.Printf("->class_%04X_function_%04X(", uclass, targetOffset);
00441 for(std::deque<Node *>::const_reverse_iterator i=pnode.rbegin(); i!=pnode.rend(); ++i)
00442 {
00443 if(i!=pnode.rbegin()) o.Print(", ");
00444 (*i)->print_unk(o, isize);
00445 }
00446 o.Putchar(')');
00447 break;
00448 }
00449 default: assert(print_assert(this));
00450 }
00451 }
00452
00453 void DCCallNode::print_asm(Console &o) const
00454 {
00455 print_linenum_asm(o);
00456 switch(ctype)
00457 {
00458 case CALLI:
00459 {
00460 for(std::deque<Node *>::const_reverse_iterator i=pnode.rbegin(); i!=pnode.rend(); ++i)
00461 {
00462 (*i)->print_asm(o); o.Putchar('\n');
00463 }
00464 Node::print_asm(o);
00465 o.Printf("calli\t\t%02Xh %04Xh", spsize, intrinsic);
00466 for(std::list<DCCallPostfixNode *>::const_reverse_iterator i=freenodes.rbegin(); i!=freenodes.rend(); ++i)
00467 {
00468 o.Putchar('\n'); (*i)->print_asm(o);
00469 }
00470
00471 if(addSP!=0)
00472 {
00473 o.Putchar('\n');
00474 addSP->print_asm(o);
00475 }
00476 if(rtype()!=Type::T_VOID)
00477 {
00478 assert(retVal!=0);
00479 o.Putchar('\n');
00480 retVal->print_asm(o);
00481 }
00482 break;
00483 }
00484 case CALL:
00485 {
00486 for(std::deque<Node *>::const_reverse_iterator i=pnode.rbegin(); i!=pnode.rend(); ++i)
00487 {
00488 (*i)->print_asm(o); o.Putchar('\n');
00489 }
00490 if(pnode.size()==0)
00491 o.Putchar('\n');
00492
00493 Node::print_asm(o);
00494 o.Printf("call\t\t%04X:%04X\n", uclass, targetOffset);
00495
00496 if(addSP!=0)
00497 addSP->print_asm(o);
00498 if(rtype()!=Type::T_VOID)
00499 {
00500 assert(retVal!=0);
00501 o.Putchar('\n');
00502 retVal->print_asm(o);
00503 }
00504
00505 break;
00506 }
00507 case SPAWN:
00508 {
00509 for(std::deque<Node *>::const_reverse_iterator i=pnode.rbegin(); i!=pnode.rend(); ++i)
00510 {
00511 (*i)->print_asm(o); o.Putchar('\n');
00512 }
00513 assert((thispsize>0 && thisP!=0) || print_assert(this));
00514 if(thispsize)
00515 thisP->print_asm(o);
00516 Node::print_asm(o);
00517 o.Printf("call\t\t%04X:%04X", uclass, targetOffset);
00518 o.Putchar('\n');
00519 if(addSP!=0)
00520 addSP->print_asm(o);
00521 if(rtype()!=Type::T_VOID)
00522 {
00523 assert(retVal!=0);
00524 o.Putchar('\n');
00525 retVal->print_asm(o);
00526 }
00527
00528 break;
00529 }
00530 default: assert(print_assert(this));
00531 }
00532 }
00533
00534 void DCCallNode::print_bin(ODequeDataSource &o) const
00535 {
00536 print_linenum_bin(o);
00537 switch(ctype)
00538 {
00539 case CALLI:
00540 {
00541 for(std::deque<Node *>::const_reverse_iterator i=pnode.rbegin(); i!=pnode.rend(); ++i)
00542 {
00543 (*i)->print_bin(o);
00544 }
00545 o.write1(0x0F);
00546 o.write1(spsize);
00547 o.write2(intrinsic);
00548 if(addSP!=0)
00549 addSP->print_bin(o);
00550 if(rtype()!=Type::T_VOID)
00551 {
00552 assert(retVal!=0);
00553 retVal->print_bin(o);
00554 }
00555 break;
00556 }
00557 case CALL:
00558 {
00559 for(std::deque<Node *>::const_reverse_iterator i=pnode.rbegin(); i!=pnode.rend(); ++i)
00560 {
00561 (*i)->print_bin(o);
00562 }
00563 o.write1(0x11);
00564 o.write2(uclass);
00565 o.write2(targetOffset);
00566 if(addSP!=0)
00567 addSP->print_bin(o);
00568 if(rtype()!=Type::T_VOID)
00569 {
00570 assert(retVal!=0);
00571 retVal->print_bin(o);
00572 }
00573 break;
00574 }
00575 case SPAWN:
00576 {
00577 for(std::deque<Node *>::const_reverse_iterator i=pnode.rbegin(); i!=pnode.rend(); ++i)
00578 {
00579 (*i)->print_bin(o);
00580 }
00581 assert(thispsize>0 || thisP!=0 || print_assert(this));
00582 if(thispsize)
00583 thisP->print_bin(o);
00584 o.write1(0x11);
00585 o.write2(uclass);
00586 o.write2(targetOffset);
00587 if(addSP!=0)
00588 addSP->print_bin(o);
00589 if(rtype()!=Type::T_VOID)
00590 {
00591 assert(retVal!=0);
00592 retVal->print_bin(o);
00593 }
00594 break;
00595 }
00596 default: assert(print_assert(this));
00597 }
00598 }
00599
00600
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762