statement.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2002-2006, Trent Waddington and Mike Van Emmerik
00003  *
00004  * See the file "LICENSE.TERMS" for information on usage and
00005  * redistribution of this file, and for a DISCLAIMER OF ALL
00006  * WARRANTIES.
00007  *
00008  */
00009 
00010 /*==============================================================================
00011  * FILE:       statement.cpp
00012  * OVERVIEW:   Implementation of the Statement and related classes.
00013  *             (Was dataflow.cpp a long time ago)
00014  *============================================================================*/
00015 
00016 /*
00017  * $Revision: 1.233 $   // 1.148.2.38
00018  * 03 Jul 02 - Trent: Created
00019  * 25 Jul 03 - Mike: dataflow.cpp, hrtl.cpp -> statement.cpp
00020  */
00021 
00022 /*==============================================================================
00023  * Dependencies.
00024  *============================================================================*/
00025 
00026 #include <assert.h>
00027 #include <iomanip>          // For setfill etc
00028 
00029 #include <sstream>
00030 #include <algorithm>
00031 #include "statement.h"
00032 #include "exp.h"
00033 #include "cfg.h"
00034 #include "proc.h"
00035 #include "prog.h"
00036 #include "boomerang.h"
00037 #include "rtl.h"            // For debugging code
00038 #include "util.h"
00039 #include "signature.h"
00040 #include "visitor.h"
00041 #include "dataflow.h"
00042 #include "log.h"
00043 
00044 
00045 extern char debug_buffer[];      // For prints functions
00046 
00047 #if defined(_MSC_VER) && _MSC_VER < 1310            // Ugh - MSC 7.0 doesn't have advance
00048 #define my_advance(aa, n) \
00049     for (int zz = 0; zz < n; zz++) \
00050         aa++;
00051 #else
00052 #define my_advance(aa, n) \
00053     advance(aa, n);
00054 #endif
00055 
00056 void Statement::setProc(UserProc *p)
00057 {
00058     proc = p;
00059     LocationSet exps;
00060     addUsedLocs(exps);
00061     LocationSet defs;
00062     getDefinitions(defs);
00063     exps.makeUnion(defs);
00064     LocationSet::iterator ll;
00065     for (ll = exps.begin(); ll != exps.end(); ll++) {
00066         Location *l = dynamic_cast<Location*>(*ll);
00067         if (l) {
00068             l->setProc(p);
00069         }
00070     }
00071 }
00072 
00073 Exp *Statement::getExpAtLex(unsigned int begin, unsigned int end)
00074 {
00075     return NULL;
00076 }
00077 
00078 bool Statement::mayAlias(Exp *e1, Exp *e2, int size) { 
00079     if (*e1 == *e2) return true;
00080     // Pass the expressions both ways. Saves checking things like m[exp] vs m[exp+K] and m[exp+K] vs m[exp] explicitly
00081     // (only need to check one of these cases)
00082     bool b =  (calcMayAlias(e1, e2, size) && calcMayAlias(e2, e1, size)); 
00083     if (b && VERBOSE) {
00084         LOG << "May alias: " << e1 << " and " << e2 << " size " << size << "\n";
00085     }
00086     return b;
00087 }
00088 
00089 // returns true if e1 may alias e2
00090 bool Statement::calcMayAlias(Exp *e1, Exp *e2, int size) {
00091     // currently only considers memory aliasing..
00092     if (!e1->isMemOf() || !e2->isMemOf()) {
00093         return false;
00094     }
00095     Exp *e1a = e1->getSubExp1();
00096     Exp *e2a = e2->getSubExp1();
00097     // constant memory accesses
00098     if (e1a->isIntConst() && e2a->isIntConst()) {
00099         ADDRESS a1 = ((Const*)e1a)->getAddr();
00100         ADDRESS a2 = ((Const*)e2a)->getAddr();
00101         int diff = a1 - a2;
00102         if (diff < 0) diff = -diff;
00103         if (diff*8 >= size) return false;
00104     }
00105     // same left op constant memory accesses
00106     if (e1a->getArity() == 2 && e1a->getOper() == e2a->getOper() && e1a->getSubExp2()->isIntConst() &&
00107             e2a->getSubExp2()->isIntConst() && *e1a->getSubExp1() == *e2a->getSubExp1()) {
00108         int i1 = ((Const*)e1a->getSubExp2())->getInt();
00109         int i2 = ((Const*)e2a->getSubExp2())->getInt();
00110         int diff = i1 - i2;
00111         if (diff < 0) diff = -diff;
00112         if (diff*8 >= size) return false;
00113     }
00114     // [left] vs [left +/- constant] memory accesses
00115     if ((e2a->getOper() == opPlus || e2a->getOper() == opMinus) && *e1a == *e2a->getSubExp1() &&
00116             e2a->getSubExp2()->isIntConst()) {
00117         int i1 = 0;
00118         int i2 = ((Const*)e2a->getSubExp2())->getInt();
00119         int diff = i1 - i2;
00120         if (diff < 0) diff = -diff;
00121         if (diff*8 >= size) return false;
00122     }
00123     // Don't need [left +/- constant ] vs [left] because called twice with
00124     // args reversed
00125     return true;
00126 }
00127 
00128 RangeMap Statement::getInputRanges()
00129 {
00130     if (!isFirstStatementInBB()) {
00131         savedInputRanges = getPreviousStatementInBB()->getRanges();
00132         return savedInputRanges;
00133     }
00134 
00135     assert(pbb && pbb->getNumInEdges() <= 1);
00136     RangeMap input;
00137     if (pbb->getNumInEdges() == 0) {
00138         // setup input for start of procedure
00139         Range ra24(1, 0, 0, new Unary(opInitValueOf, Location::regOf(24)));
00140         Range ra25(1, 0, 0, new Unary(opInitValueOf, Location::regOf(25)));
00141         Range ra26(1, 0, 0, new Unary(opInitValueOf, Location::regOf(26)));
00142         Range ra27(1, 0, 0, new Unary(opInitValueOf, Location::regOf(27)));
00143         Range ra28(1, 0, 0, new Unary(opInitValueOf, Location::regOf(28)));
00144         Range ra29(1, 0, 0, new Unary(opInitValueOf, Location::regOf(29)));
00145         Range ra30(1, 0, 0, new Unary(opInitValueOf, Location::regOf(30)));
00146         Range ra31(1, 0, 0, new Unary(opInitValueOf, Location::regOf(31)));
00147         Range rpc(1, 0, 0, new Unary(opInitValueOf,  new Terminal(opPC)));
00148         input.addRange(Location::regOf(24), ra24);
00149         input.addRange(Location::regOf(25), ra25);
00150         input.addRange(Location::regOf(26), ra26);
00151         input.addRange(Location::regOf(27), ra27);
00152         input.addRange(Location::regOf(28), ra28);
00153         input.addRange(Location::regOf(29), ra29);
00154         input.addRange(Location::regOf(30), ra30);
00155         input.addRange(Location::regOf(31), ra31);
00156         input.addRange(new Terminal(opPC), rpc);
00157     } else {
00158         PBB pred = pbb->getInEdges()[0];
00159         Statement *last = pred->getLastStmt();
00160         assert(last);
00161         if (pred->getNumOutEdges() != 2) {
00162             input = last->getRanges();
00163         } else {
00164             assert(pred->getNumOutEdges() == 2);
00165             assert(last->isBranch());
00166             input = ((BranchStatement*)last)->getRangesForOutEdgeTo(pbb);
00167         }
00168     }
00169 
00170     savedInputRanges = input;
00171 
00172     return input;
00173 }
00174 
00175 void Statement::updateRanges(RangeMap &output, std::list<Statement*> &execution_paths, bool notTaken)
00176 {
00177     if (!output.isSubset(notTaken ? ((BranchStatement*)this)->getRanges2Ref() : ranges)) {
00178         if (notTaken)
00179             ((BranchStatement*)this)->setRanges2(output);
00180         else
00181             ranges = output;
00182         if (isLastStatementInBB()) {
00183             if (pbb->getNumOutEdges()) {
00184                 int arc = 0;
00185                 if (isBranch()) {
00186                     if (pbb->getOutEdge(0)->getLowAddr() != ((BranchStatement*)this)->getFixedDest())
00187                         arc = 1;
00188                     if (notTaken)
00189                         arc ^= 1;
00190                 }
00191                 execution_paths.push_back(pbb->getOutEdge(arc)->getFirstStmt());
00192             }
00193         } else
00194             execution_paths.push_back(getNextStatementInBB());
00195     }
00196 }
00197 
00198 void Statement::rangeAnalysis(std::list<Statement*> &execution_paths)
00199 {
00200     RangeMap output = getInputRanges();
00201     updateRanges(output, execution_paths);
00202 }
00203 
00204 void Assign::rangeAnalysis(std::list<Statement*> &execution_paths)
00205 {
00206     RangeMap output = getInputRanges();
00207     Exp *a_lhs = lhs->clone();
00208     if (a_lhs->isFlags()) {
00209         // special hacks for flags
00210         assert(rhs->isFlagCall());
00211         Exp *a_rhs = rhs->clone();
00212         if (a_rhs->getSubExp2()->getSubExp1()->isMemOf())
00213             a_rhs->getSubExp2()->getSubExp1()->setSubExp1(
00214                 output.substInto(a_rhs->getSubExp2()->getSubExp1()->getSubExp1()));
00215         if (!a_rhs->getSubExp2()->getSubExp2()->isTerminal() &&
00216             a_rhs->getSubExp2()->getSubExp2()->getSubExp1()->isMemOf())
00217             a_rhs->getSubExp2()->getSubExp2()->getSubExp1()->setSubExp1(
00218                 output.substInto(a_rhs->getSubExp2()->getSubExp2()->getSubExp1()->getSubExp1()));
00219         Range ra(1, 0, 0, a_rhs);       
00220         output.addRange(a_lhs, ra);
00221     } else {
00222         if (a_lhs->isMemOf())
00223             a_lhs->setSubExp1(output.substInto(a_lhs->getSubExp1()->clone()));
00224         Exp *a_rhs = output.substInto(rhs->clone());
00225         if (a_rhs->isMemOf() && a_rhs->getSubExp1()->getOper() == opInitValueOf &&
00226             a_rhs->getSubExp1()->getSubExp1()->isRegOfK() &&
00227             ((Const*)a_rhs->getSubExp1()->getSubExp1()->getSubExp1())->getInt() == 28)
00228             a_rhs = new Unary(opInitValueOf, new Terminal(opPC));   // nice hack
00229         if (VERBOSE && DEBUG_RANGE_ANALYSIS)
00230             LOG << "a_rhs is " << a_rhs << "\n";
00231         if (a_rhs->isMemOf() && a_rhs->getSubExp1()->isIntConst()) {
00232             ADDRESS c = ((Const*)a_rhs->getSubExp1())->getInt();
00233             if (proc->getProg()->isDynamicLinkedProcPointer(c)) {
00234                 char *nam = (char*)proc->getProg()->GetDynamicProcName(c);
00235                 if (nam) {
00236                     a_rhs = new Const(nam);
00237                     if (VERBOSE && DEBUG_RANGE_ANALYSIS)
00238                         LOG << "a_rhs is a dynamic proc pointer to " << nam << "\n";
00239                 }
00240             } else if (proc->getProg()->isReadOnly(c)) {
00241                 switch(type->getSize()) {
00242                     case 8:
00243                         a_rhs = new Const(proc->getProg()->readNative1(c));
00244                         break;
00245                     case 16:
00246                         a_rhs = new Const(proc->getProg()->readNative2(c));
00247                         break;
00248                     case 32:
00249                         a_rhs = new Const(proc->getProg()->readNative4(c));
00250                         break;
00251                     default:
00252                         LOG << "error: unhandled type size " << type->getSize() << " for reading native address\n";
00253                 }
00254             } else
00255                 if (VERBOSE && DEBUG_RANGE_ANALYSIS)
00256                     LOG << c << " is not dynamically linked proc pointer or in read only memory\n";
00257         }
00258         if ((a_rhs->getOper() == opPlus || a_rhs->getOper() == opMinus) && 
00259             a_rhs->getSubExp2()->isIntConst() && output.hasRange(a_rhs->getSubExp1())) {
00260             Range &r = output.getRange(a_rhs->getSubExp1());
00261             int c = ((Const*)a_rhs->getSubExp2())->getInt();
00262             if (a_rhs->getOper() == opPlus) {
00263                 Range ra(1, r.getLowerBound() != Range::MIN ? r.getLowerBound() + c : Range::MIN,
00264                     r.getUpperBound() != Range::MAX? r.getUpperBound() + c : Range::MAX, r.getBase());
00265                 output.addRange(a_lhs, ra);
00266             } else {
00267                 Range ra(1, r.getLowerBound() != Range::MIN ? r.getLowerBound() - c : Range::MIN,
00268                     r.getUpperBound() != Range::MAX ? r.getUpperBound() - c : Range::MAX, r.getBase());
00269                 output.addRange(a_lhs, ra);
00270             }
00271         } else {
00272             if (output.hasRange(a_rhs)) {
00273                 output.addRange(a_lhs, output.getRange(a_rhs));
00274             } else {
00275                 Exp *result;
00276                 if (a_rhs->getMemDepth() == 0 && !a_rhs->search(new Unary(opRegOf, new Terminal(opWild)), result) &&
00277                     !a_rhs->search(new Unary(opTemp, new Terminal(opWild)), result)) {
00278                     if (a_rhs->isIntConst()) {
00279                         Range ra(1, ((Const*)a_rhs)->getInt(), ((Const*)a_rhs)->getInt(), new Const(0));
00280                         output.addRange(a_lhs, ra);
00281                     }
00282                     else {
00283                         Range ra(1, 0, 0, a_rhs);
00284                         output.addRange(a_lhs, ra);
00285                     }
00286                 } else {
00287                     Range empty;
00288                     output.addRange(a_lhs, empty);
00289                 }
00290             }
00291         }
00292     }
00293     if (VERBOSE && DEBUG_RANGE_ANALYSIS)
00294         LOG << "added " << a_lhs << " -> " << output.getRange(a_lhs) << "\n";
00295     updateRanges(output, execution_paths);
00296     if (VERBOSE && DEBUG_RANGE_ANALYSIS)
00297         LOG << this << "\n";
00298 }
00299 
00300 void BranchStatement::limitOutputWithCondition(RangeMap &output, Exp *e)
00301 {
00302     assert(e);
00303     if (output.hasRange(e->getSubExp1())) {
00304         Range &r = output.getRange(e->getSubExp1());
00305         if (e->getSubExp2()->isIntConst() && r.getBase()->isIntConst() && ((Const*)r.getBase())->getInt() == 0) {
00306             int c = ((Const*)e->getSubExp2())->getInt();
00307             switch(e->getOper()) {
00308                 case opLess:
00309                 case opLessUns: {
00310                     Range ra(r.getStride(), r.getLowerBound() >= c ? c - 1 : r.getLowerBound(),
00311                         r.getUpperBound() >= c ? c - 1 : r.getUpperBound(), r.getBase());
00312                     output.addRange(e->getSubExp1(), ra);
00313                     break;
00314                 }
00315                 case opLessEq:
00316                 case opLessEqUns: {
00317                     Range ra(r.getStride(), r.getLowerBound() > c ? c : r.getLowerBound(),
00318                         r.getUpperBound() > c ? c : r.getUpperBound(), r.getBase());
00319                     output.addRange(e->getSubExp1(), ra);
00320                     break;
00321                 }
00322                 case opGtr:
00323                 case opGtrUns: {
00324                     Range ra(r.getStride(), r.getLowerBound() <= c ? c + 1 : r.getLowerBound(),
00325                         r.getUpperBound() <= c ? c + 1 : r.getUpperBound(), r.getBase());
00326                     output.addRange(e->getSubExp1(), ra);
00327                     break;
00328                 }
00329                 case opGtrEq:
00330                 case opGtrEqUns: {
00331                     Range ra(r.getStride(), r.getLowerBound() < c ? c : r.getLowerBound(),
00332                         r.getUpperBound() < c ? c : r.getUpperBound(), r.getBase());
00333                     output.addRange(e->getSubExp1(), ra);
00334                     break;
00335                 }
00336                 case opEquals: {
00337                     Range ra(r.getStride(), c, c, r.getBase());
00338                     output.addRange(e->getSubExp1(), ra);
00339                     break;
00340                 }
00341                 case opNotEqual: {
00342                     Range ra(r.getStride(), r.getLowerBound() == c ? c + 1 : r.getLowerBound(),
00343                         r.getUpperBound() == c ? c - 1 : r.getUpperBound(), r.getBase());
00344                     output.addRange(e->getSubExp1(), ra);
00345                     break;
00346                 }
00347                 default:
00348                     break;
00349             }
00350         }
00351     }
00352 }
00353 
00354 void BranchStatement::rangeAnalysis(std::list<Statement*> &execution_paths)
00355 {
00356     RangeMap output = getInputRanges();
00357 
00358     Exp *e = NULL;
00359     // try to hack up a useful expression for this branch
00360     OPER op = pCond->getOper();
00361     if (op == opLess || op == opLessEq || op == opGtr || op == opGtrEq ||
00362         op == opLessUns || op == opLessEqUns || op == opGtrUns || op == opGtrEqUns ||
00363         op == opEquals || op == opNotEqual) {
00364         if (pCond->getSubExp1()->isFlags() && output.hasRange(pCond->getSubExp1())) {
00365             Range &r = output.getRange(pCond->getSubExp1());
00366             if (r.getBase()->isFlagCall() && 
00367                 r.getBase()->getSubExp2()->getOper() == opList &&
00368                 r.getBase()->getSubExp2()->getSubExp2()->getOper() == opList) {
00369                 e = new Binary(op, r.getBase()->getSubExp2()->getSubExp1()->clone(), r.getBase()->getSubExp2()->getSubExp2()->getSubExp1()->clone());
00370                 if (VERBOSE && DEBUG_RANGE_ANALYSIS)
00371                     LOG << "calculated condition " << e << "\n";
00372             }
00373         }
00374     }
00375 
00376     if (e)
00377         limitOutputWithCondition(output, e);
00378     updateRanges(output, execution_paths);
00379     output = getInputRanges();
00380     if (e)
00381         limitOutputWithCondition(output, (new Unary(opNot, e))->simplify());
00382     updateRanges(output, execution_paths, true);
00383 
00384     if (VERBOSE && DEBUG_RANGE_ANALYSIS)
00385         LOG << this << "\n";
00386 }
00387 
00388 void JunctionStatement::rangeAnalysis(std::list<Statement*> &execution_paths)
00389 {
00390     RangeMap input;
00391     if (VERBOSE && DEBUG_RANGE_ANALYSIS)
00392         LOG << "unioning {\n";
00393     for (int i = 0; i < pbb->getNumInEdges(); i++) {
00394         Statement *last = pbb->getInEdges()[i]->getLastStmt();
00395         if (VERBOSE && DEBUG_RANGE_ANALYSIS)
00396             LOG << "  in BB: " << pbb->getInEdges()[i]->getLowAddr() << " " << last << "\n";
00397         if (last->isBranch()) {
00398             input.unionwith(((BranchStatement*)last)->getRangesForOutEdgeTo(pbb));
00399         } else {
00400             if (last->isCall()) {
00401                 Proc *d = ((CallStatement*)last)->getDestProc();
00402                 if (d && !d->isLib() && ((UserProc*)d)->getCFG()->findRetNode() == NULL) {
00403                     if (VERBOSE && DEBUG_RANGE_ANALYSIS)
00404                         LOG << "ignoring ranges from call to proc with no ret node\n";
00405                 } else
00406                     input.unionwith(last->getRanges());
00407             } else
00408                 input.unionwith(last->getRanges());
00409         }
00410     }
00411     if (VERBOSE && DEBUG_RANGE_ANALYSIS)
00412         LOG << "}\n";
00413 
00414     if (!input.isSubset(ranges)) {
00415         RangeMap output = input;
00416 
00417         if (output.hasRange(Location::regOf(28))) {
00418             Range &r = output.getRange(Location::regOf(28));
00419             if (r.getLowerBound() != r.getUpperBound() && r.getLowerBound() != Range::MIN) {
00420                 if (VERBOSE)
00421                     LOG << "stack height assumption violated " << r << " my bb: " << pbb->getLowAddr() << "\n";
00422                 proc->printToLog();
00423                 assert(false);
00424             }
00425         }
00426 
00427         if (isLoopJunction()) {
00428             output = ranges;
00429             output.widenwith(input);
00430         }
00431 
00432         updateRanges(output, execution_paths);
00433     }
00434 
00435     if (VERBOSE && DEBUG_RANGE_ANALYSIS)
00436         LOG << this << "\n";
00437 }
00438 
00439 void CallStatement::rangeAnalysis(std::list<Statement*> &execution_paths)
00440 {
00441     RangeMap output = getInputRanges();
00442 
00443     if (this->procDest == NULL) {
00444         // note this assumes the call is only to one proc.. could be bad.
00445         Exp *d = output.substInto(getDest()->clone());
00446         if (d->isIntConst() || d->isStrConst()) {
00447             if (d->isIntConst()) {
00448                 ADDRESS dest = ((Const*)d)->getInt();
00449                 procDest = proc->getProg()->setNewProc(dest);
00450             } else {
00451                 procDest = proc->getProg()->getLibraryProc(((Const*)d)->getStr());
00452             }
00453             if (procDest) {
00454                 Signature *sig = procDest->getSignature();
00455                 pDest = d;
00456                 arguments.clear();
00457                 for (unsigned i = 0; i < sig->getNumParams(); i++) {
00458                     Exp* a = sig->getParamExp(i);
00459                     Assign* as = new Assign(new VoidType(), a->clone(), a->clone());
00460                     as->setProc(proc);
00461                     as->setBB(pbb);
00462                     arguments.append(as);
00463                 }
00464                 signature = procDest->getSignature()->clone();
00465                 m_isComputed = false;
00466                 proc->undoComputedBB(this);
00467                 proc->addCallee(procDest);
00468                 LOG << "replaced indirect call with call to " << procDest->getName() << "\n";
00469             }
00470         }
00471     }
00472 
00473     if (output.hasRange(Location::regOf(28))) {
00474         Range &r = output.getRange(Location::regOf(28));
00475         int c = 4;
00476         if (procDest == NULL) {
00477             LOG << "using push count hack to guess number of params\n";
00478             Statement *prev = this->getPreviousStatementInBB();
00479             while(prev) {
00480                 if (prev->isAssign() && ((Assign*)prev)->getLeft()->isMemOf() &&
00481                     ((Assign*)prev)->getLeft()->getSubExp1()->isRegOfK() &&
00482                     ((Const*)((Assign*)prev)->getLeft()->getSubExp1()->getSubExp1())->getInt() == 28 &&
00483                     ((Assign*)prev)->getRight()->getOper() != opPC) {
00484                     c += 4;
00485                 }
00486                 prev = prev->getPreviousStatementInBB();
00487             }
00488         } else if (procDest->getSignature()->getConvention() == CONV_PASCAL)
00489             c += procDest->getSignature()->getNumParams() * 4;
00490         else if (!strncmp(procDest->getName(), "__imp_", 6)) {
00491             Statement *first = ((UserProc*)procDest)->getCFG()->getEntryBB()->getFirstStmt();
00492             assert(first && first->isCall());
00493             Proc *d = ((CallStatement*)first)->getDestProc();
00494             if (d->getSignature()->getConvention() == CONV_PASCAL)
00495                 c += d->getSignature()->getNumParams() * 4;             
00496         } else if (!procDest->isLib()) {
00497             UserProc *p = (UserProc*)procDest;
00498             if (VERBOSE) {
00499                 LOG << "== checking for number of bytes popped ==\n";
00500                 p->printToLog();
00501                 LOG << "== end it ==\n";
00502             }
00503             Exp *eq = p->getProven(Location::regOf(28));
00504             if (eq) {
00505                 if (VERBOSE)
00506                     LOG << "found proven " << eq << "\n";
00507                 if (eq->getOper() == opPlus && *eq->getSubExp1() == *Location::regOf(28) &&
00508                         eq->getSubExp2()->isIntConst()) {
00509                     c = ((Const*)eq->getSubExp2())->getInt();
00510                 } else
00511                     eq = NULL;
00512             }
00513             PBB retbb = p->getCFG()->findRetNode();
00514             if (retbb && eq == NULL) {
00515                 Statement *last = retbb->getLastStmt();
00516                 assert(last);
00517                 if (last->isReturn()) {
00518                     last->setBB(retbb);
00519                     last = last->getPreviousStatementInBB();
00520                 }
00521                 if (last == NULL) {
00522                     // call followed by a ret, sigh
00523                     for (int i = 0; i < retbb->getNumInEdges(); i++) {
00524                         last = retbb->getInEdges()[i]->getLastStmt();
00525                         if (last->isCall())
00526                             break;
00527                     }
00528                     if (last->isCall()) {
00529                         Proc *d = ((CallStatement*)last)->getDestProc();
00530                         if (d && d->getSignature()->getConvention() == CONV_PASCAL)
00531                             c += d->getSignature()->getNumParams() * 4;
00532                     }
00533                     last = NULL;
00534                 }
00535                 if (last && last->isAssign()) {
00536                     //LOG << "checking last statement " << last << " for number of bytes popped\n";
00537                     Assign *a = (Assign*)last;
00538                     assert(a->getLeft()->isRegOfK() && ((Const*)a->getLeft()->getSubExp1())->getInt() == 28);
00539                     Exp *t = a->getRight()->clone()->simplifyArith();
00540                     assert(t->getOper() == opPlus &&
00541                         t->getSubExp1()->isRegOfK() &&
00542                         ((Const*)t->getSubExp1()->getSubExp1())->getInt() == 28);
00543                     assert(t->getSubExp2()->isIntConst());
00544                     c = ((Const*)t->getSubExp2())->getInt();
00545                 }
00546             }
00547         }
00548         Range ra(r.getStride(), r.getLowerBound() == Range::MIN ? Range::MIN : r.getLowerBound() + c,
00549             r.getUpperBound() == Range::MAX ? Range::MAX : r.getUpperBound() + c, r.getBase());
00550         output.addRange(Location::regOf(28), ra);
00551     }
00552     updateRanges(output, execution_paths);
00553 }
00554 
00555 bool JunctionStatement::isLoopJunction()
00556 {
00557     for (int i = 0; i < pbb->getNumInEdges(); i++) 
00558         if (pbb->isBackEdge(i))
00559             return true;
00560     return false;
00561 }
00562 
00563 RangeMap &BranchStatement::getRangesForOutEdgeTo(PBB out)
00564 {
00565     assert(this->getFixedDest() != NO_ADDRESS);
00566     if (out->getLowAddr() == this->getFixedDest())
00567         return ranges;
00568     return ranges2;
00569 }
00570 
00571 bool Statement::isFirstStatementInBB()
00572 {
00573     assert(pbb);
00574     assert(pbb->getRTLs());
00575     assert(pbb->getRTLs()->size());
00576     assert(pbb->getRTLs()->front());
00577     assert(pbb->getRTLs()->front()->getList().size());
00578     return this == pbb->getRTLs()->front()->getList().front();
00579 }
00580 
00581 bool Statement::isLastStatementInBB()
00582 {
00583     assert(pbb);
00584     return this == pbb->getLastStmt();
00585 }
00586 
00587 Statement*  Statement::getPreviousStatementInBB()
00588 {
00589     assert(pbb);
00590     std::list<RTL*> *rtls = pbb->getRTLs();
00591     assert(rtls);
00592     Statement *previous = NULL;
00593     for (std::list<RTL*>::iterator rit = rtls->begin(); rit != rtls->end(); rit++) {
00594         RTL *rtl = *rit;
00595         for (RTL::iterator it = rtl->getList().begin(); it != rtl->getList().end(); it++) {
00596             if (*it == this)
00597                 return previous;
00598             previous = *it;
00599         }
00600     }
00601     return NULL;
00602 }
00603 
00604 Statement *Statement::getNextStatementInBB()
00605 {
00606     assert(pbb);
00607     std::list<RTL*> *rtls = pbb->getRTLs();
00608     assert(rtls);
00609     bool wantNext = false;
00610     for (std::list<RTL*>::iterator rit = rtls->begin(); rit != rtls->end(); rit++) {
00611         RTL *rtl = *rit;
00612         for (RTL::iterator it = rtl->getList().begin(); it != rtl->getList().end(); it++) {
00613             if (wantNext)
00614                 return *it;
00615             if (*it == this)
00616                 wantNext = true;
00617         }
00618     }
00619     return NULL;
00620 }
00621 
00622 /*==============================================================================
00623  * FUNCTION:        operator<<
00624  * OVERVIEW:        Output operator for Statement*
00625  *                  Just makes it easier to use e.g. std::cerr << myStmtStar
00626  * PARAMETERS:      os: output stream to send to
00627  *                  p: ptr to Statement to print to the stream
00628  * RETURNS:         copy of os (for concatenation)
00629  *============================================================================*/
00630 std::ostream& operator<<(std::ostream& os, Statement* s) {
00631     if (s == NULL) {os << "NULL "; return os;}
00632     s->print(os);
00633     return os;
00634 }
00635 
00636 bool Statement::isFlagAssgn() {
00637     if (kind != STMT_ASSIGN)
00638         return false;
00639     OPER op = ((Assign*)this)->getRight()->getOper();
00640     return (op == opFlagCall);
00641 }
00642 
00643 char* Statement::prints() {
00644     std::ostringstream ost;
00645     print(ost);
00646     strncpy(debug_buffer, ost.str().c_str(), DEBUG_BUFSIZE-1);
00647     debug_buffer[DEBUG_BUFSIZE-1] = '\0';
00648     return debug_buffer;
00649 }
00650 
00651 // This version prints much better in gdb
00652 void Statement::dump() {
00653     print(std::cerr);
00654     std::cerr << "\n";
00655 }
00656 
00657 
00658 /* This function is designed to find basic flag calls, plus in addition two variations seen with Pentium FP code.
00659     These variations involve ANDing and/or XORing with constants. So it should return true for these values of e:
00660     ADDFLAGS(...)
00661     SETFFLAGS(...) & 0x45
00662     (SETFFLAGS(...) & 0x45) ^ 0x40
00663     FIXME: this may not be needed any more...
00664 */
00665 bool hasSetFlags(Exp* e) {
00666     if (e->isFlagCall()) return true;
00667     OPER op = e->getOper();
00668     if (op != opBitAnd && op != opBitXor) return false;
00669     Exp* left  = ((Binary*)e)->getSubExp1();
00670     Exp* right = ((Binary*)e)->getSubExp2();
00671     if (!right->isIntConst()) return false;
00672     if (left->isFlagCall()) {
00673 std::cerr << "hasSetFlags returns true with " << e << "\n";
00674         return true;
00675     }
00676     op = left->getOper();
00677     if (op != opBitAnd && op != opBitXor) return false;
00678     right = ((Binary*)left)->getSubExp2();
00679     left  = ((Binary*)left)->getSubExp1();
00680     if (!right->isIntConst()) return false;
00681     bool ret = left->isFlagCall();
00682 if (ret)
00683  std::cerr << "hasSetFlags returns true with " << e << "\n";
00684     return ret;
00685 }
00686 
00687 // Return true if can propagate to Exp* e (must be a RefExp to return true)
00688 // Note: does not consider whether e is able to be renamed (from a memory Primitive point of view), only if the
00689 // definition can be propagated TO this stmt
00690 // Note: static member function
00691 bool Statement::canPropagateToExp(Exp*e) {
00692     if (!e->isSubscript()) return false;
00693     if (((RefExp*)e)->isImplicitDef())
00694         // Can't propagate statement "-" or "0" (implicit assignments)
00695         return false;
00696     Statement* def = ((RefExp*)e)->getDef();
00697 //  if (def == this)
00698         // Don't propagate to self! Can happen with %pc's (?!)
00699 //      return false;
00700     if (def->isNullStatement())
00701         // Don't propagate a null statement! Can happen with %pc's (would have no effect, and would infinitely loop)
00702         return false;
00703     if (!def->isAssign()) return false;     // Only propagate ordinary assignments (so far)
00704     Assign* adef = (Assign*)def;
00705 
00706     if (adef->getType()->isArray()) {
00707         // Assigning to an array, don't propagate (Could be alias problems?)
00708         return false;
00709     }
00710     return true;
00711 }
00712 
00713 // Return true if any change; set convert if an indirect call statement is converted to direct (else unchanged)
00714 // destCounts is a set of maps from location to number of times it is used this proc
00715 // usedByDomPhi is a set of subscripted locations used in phi statements
00716 static int progress = 0;
00717 bool Statement::propagateTo(bool& convert, std::map<Exp*, int, lessExpStar>* destCounts /* = NULL */,
00718         LocationSet* usedByDomPhi /* = NULL */, bool force /* = false */) {
00719     if (++progress > 1000) {
00720         std::cerr << 'p' << std::flush;
00721         progress = 0;
00722     }
00723     bool change;
00724     int changes = 0;
00725     // int sp = proc->getSignature()->getStackRegister(proc->getProg());
00726     // Exp* regSp = Location::regOf(sp);
00727     int propMaxDepth = Boomerang::get()->propMaxDepth;
00728     do {
00729         LocationSet exps;
00730         addUsedLocs(exps, true);        // True to also add uses from collectors. For example, want to propagate into
00731                                         // the reaching definitions of calls. Third parameter defaults to false, to
00732                                         // find all locations, not just those inside m[...]
00733         LocationSet::iterator ll;
00734         change = false;                 // True if changed this iteration of the do/while loop
00735         // Example: m[r24{10}] := r25{20} + m[r26{30}]
00736         // exps has r24{10}, r25{30}, m[r26{30}], r26{30}
00737         for (ll = exps.begin(); ll != exps.end(); ll++) {
00738             Exp* e = *ll;
00739             if (!canPropagateToExp(e))
00740                 continue;
00741             Assign* def = (Assign*)((RefExp*)e)->getDef();
00742             Exp* rhs = def->getRight();
00743             // If force is true, ignore the fact that a memof should not be propagated (for switch analysis)
00744             if (rhs->containsBadMemof(proc) && !(force && rhs->isMemOf()))
00745                 // Must never propagate unsubscripted memofs, or memofs that don't yet have symbols. You could be
00746                 // propagating past a definition, thereby invalidating the IR
00747                 continue;
00748             Exp* lhs = def->getLeft();
00749 
00750             if (EXPERIMENTAL) {
00751 #if 0
00752                 // This is the old "don't propagate x=f(x)" heuristic. Hopefully it will work better now that we always
00753                 // propagate into memofs etc. However, it might need a "and we're inside the right kind of loop"
00754                 // condition
00755                 LocationSet used;
00756                 def->addUsedLocs(used);
00757                 RefExp left(def->getLeft(), (Statement*)-1);
00758                 RefExp *right = dynamic_cast<RefExp*>(def->getRight());
00759                 // Beware of x := x{something else} (because we do want to do copy propagation)
00760                 if (used.exists(&left) && !(right && *right->getSubExp1() == *left.getSubExp1()))
00761                     // We have something like eax = eax + 1
00762                     continue;
00763 #else
00764                 // This is Mike's experimental propagation limiting heuristic. At present, it is:
00765                 // for each component of def->rhs
00766                 //   test if the base expression is in the set usedByDomPhi
00767                 //   if so, check if this statement OW overwrites a parameter (like ebx = ebx-1)
00768                 //   if so, check for propagating past this overwriting statement, i.e.
00769                 //      domNum(def) <= domNum(OW) && dimNum(OW) < domNum(def)
00770                 //      if so, don't propagate (heuristic takes effect)
00771                 if (usedByDomPhi) {
00772                     LocationSet rhsComps;
00773                     rhs->addUsedLocs(rhsComps);
00774                     LocationSet::iterator rcit;
00775                     bool doNotPropagate = false;
00776                     for (rcit = rhsComps.begin(); rcit != rhsComps.end(); ++rcit) {
00777                         if (!(*rcit)->isSubscript()) continue;      // Sometimes %pc sneaks in
00778                         Exp* rhsBase = ((RefExp*)*rcit)->getSubExp1();
00779                         // We don't know the statement number for the one definition in usedInDomPhi that might exist,
00780                         // so we use findNS()
00781                         Exp* OW = usedByDomPhi->findNS(rhsBase);
00782                         if (OW) {
00783                             Statement* OWdef = ((RefExp*)OW)->getDef();
00784                             if (!OWdef->isAssign()) continue;
00785                             Exp* lhsOWdef = ((Assign*)OWdef)->getLeft();
00786                             LocationSet OWcomps;
00787                             def->addUsedLocs(OWcomps);
00788                             LocationSet::iterator cc;
00789                             bool isOverwrite = false;
00790                             for (cc = OWcomps.begin(); cc != OWcomps.end(); ++cc) {
00791                                 if (**cc *= *lhsOWdef) {
00792                                     isOverwrite = true;
00793                                     break;
00794                                 }
00795                             }
00796                             if (isOverwrite) {
00797                                 // Now check for propagating a component past OWdef
00798                                 if (def->getDomNumber() <= OWdef->getDomNumber() &&
00799                                         OWdef->getDomNumber() < dominanceNum)
00800                                     // The heuristic kicks in
00801                                     doNotPropagate = true;
00802                                     break;
00803                             }
00804 if (OW) std::cerr << "Ow is " << OW << "\n";
00805                         }
00806                     }
00807                     if (doNotPropagate) {
00808                         if (VERBOSE)
00809                             LOG << "% propagation of " << def->getNumber() << " into " << number << " prevented by the "
00810                                 "propagate past overwriting statement in loop heuristic\n";
00811                         continue;
00812                     }
00813                 }
00814             }
00815 #endif
00816 
00817             // Check if the -l flag (propMaxDepth) prevents this propagation
00818             if (destCounts && !lhs->isFlags()) {            // Always propagate to %flags
00819                 std::map<Exp*, int, lessExpStar>::iterator ff = destCounts->find(e);
00820                 if (ff != destCounts->end() && ff->second > 1 && rhs->getComplexityDepth(proc) >= propMaxDepth) {
00821                     if (!def->getRight()->containsFlags()) {
00822                         // This propagation is prevented by the -l limit
00823                         continue;
00824                     }
00825                 }
00826             }
00827             change |= doPropagateTo(e, def, convert);
00828         }
00829     } while (change && ++changes < 10);
00830     // Simplify is very costly, especially for calls. I hope that doing one simplify at the end will not affect any
00831     // result...
00832     simplify();
00833     return changes > 0;         // Note: change is only for the last time around the do/while loop
00834 }
00835 
00836 // Experimental: may want to propagate flags first, without tests about complexity or the propagation limiting heuristic
00837 bool Statement::propagateFlagsTo() {
00838     bool change = false, convert;
00839     int changes = 0;
00840     do {
00841         LocationSet exps;
00842         addUsedLocs(exps, true);
00843         LocationSet::iterator ll;
00844         for (ll = exps.begin(); ll != exps.end(); ll++) {
00845             Exp* e = *ll;
00846             if (!e->isSubscript()) continue;        // e.g. %pc
00847             Assign* def = (Assign*)((RefExp*)e)->getDef();
00848             if (def == NULL || !def->isAssign()) continue;
00849             Exp* base = ((RefExp*)e)->getSubExp1();
00850             if (base->isFlags() || base->isMainFlag()) {
00851                 change |= doPropagateTo(e, def, convert);
00852             }
00853         }
00854     } while (change && ++changes < 10);
00855     simplify();
00856     return change;
00857 }
00858 
00859 
00860 // Parameter convert is set true if an indirect call is converted to direct
00861 // Return true if a change made
00862 // Note: this procedure does not control what part of this statement is propagated to
00863 // Propagate to e from definition statement def.
00864 // Set convert to true if convert a call from indirect to direct.
00865 bool Statement::doPropagateTo(Exp* e, Assign* def, bool& convert) {
00866     // Respect the -p N switch
00867     if (Boomerang::get()->numToPropagate >= 0) {
00868         if (Boomerang::get()->numToPropagate == 0) return false;
00869             Boomerang::get()->numToPropagate--;
00870     }
00871 
00872     if (VERBOSE)
00873         LOG << "propagating " << def << "\n" << "      into " << this << "\n";
00874 
00875     bool change = replaceRef(e, def, convert);
00876     
00877     if (VERBOSE) {
00878         LOG << "     result " << this << "\n\n";
00879     }
00880     return change;
00881 }
00882 
00883 // replace a use of def->getLeft() by def->getRight() in this statement
00884 // return true if change
00885 bool Statement::replaceRef(Exp* e, Assign *def, bool& convert) {
00886     Exp* rhs = def->getRight();
00887     assert(rhs);
00888 
00889     Exp* base = ((RefExp*)e)->getSubExp1();
00890     // Could be propagating %flags into %CF
00891     Exp* lhs = def->getLeft();
00892     if (base->getOper() == opCF && lhs->isFlags()) {
00893         if (!rhs->isFlagCall())
00894             return false;
00895         char* str = ((Const*)((Binary*)rhs)->getSubExp1())->getStr();
00896         if (strncmp("SUBFLAGS", str, 8) == 0) {
00897             /* When the carry flag is used bare, and was defined in a subtract of the form lhs - rhs, then CF has
00898                the value (lhs <u rhs).  lhs and rhs are the first and second parameters of the flagcall.
00899                Note: the flagcall is a binary, with a Const (the name) and a list of expressions:
00900                  defRhs
00901                  /    \
00902             Const      opList
00903             "SUBFLAGS"  /   \
00904                        P1   opList
00905                              /   \
00906                             P2  opList
00907                                  /   \
00908                                 P3   opNil
00909             */
00910             Exp* relExp = new Binary(opLessUns,
00911                 ((Binary*)rhs)->getSubExp2()->getSubExp1(),
00912                 ((Binary*)rhs)->getSubExp2()->getSubExp2()->getSubExp1());
00913             searchAndReplace(new RefExp(new Terminal(opCF), def), relExp, true);
00914             return true;
00915         }
00916     }
00917     // need something similar for %ZF
00918     if (base->getOper() == opZF && lhs->isFlags()) {
00919         if (!rhs->isFlagCall())
00920             return false;
00921         char* str = ((Const*)((Binary*)rhs)->getSubExp1())->getStr();
00922         if (strncmp("SUBFLAGS", str, 8) == 0) {
00923             // for zf we're only interested in if the result part of the subflags is equal to zero
00924             Exp* relExp = new Binary(opEquals,
00925                 ((Binary*)rhs)->getSubExp2()->getSubExp2()->getSubExp2()->getSubExp1(),
00926                 new Const(0));
00927             searchAndReplace(new RefExp(new Terminal(opZF), def), relExp, true);
00928             return true;
00929         }
00930     }
00931 
00932 
00933     // do the replacement
00934     //bool convert = doReplaceRef(re, rhs);
00935     bool ret = searchAndReplace(e, rhs, true);      // Last parameter true to change collectors
00936     // assert(ret);
00937 
00938     if (ret && isCall()) {
00939         convert |= ((CallStatement*)this)->convertToDirect();
00940     }
00941     return ret;
00942 }
00943 
00944 bool Statement::isNullStatement() {
00945     if (kind != STMT_ASSIGN) return false;
00946     Exp* right = ((Assign*)this)->getRight();
00947     if (right->isSubscript()) {
00948         // Must refer to self to be null
00949         return this == ((RefExp*)right)->getDef();
00950     }
00951     else
00952         // Null if left == right
00953         return *((Assign*)this)->getLeft() == *right;
00954 }
00955 
00956 bool Statement::isFpush() {
00957     if (kind != STMT_ASSIGN) return false;
00958     return ((Assign*)this)->getRight()->getOper() == opFpush;
00959 }
00960 bool Statement::isFpop() {
00961     if (kind != STMT_ASSIGN) return false;
00962     return ((Assign*)this)->getRight()->getOper() == opFpop;
00963 }
00964 
00965 
00966 /*
00967  * This code was in hrtl.cpp
00968  * Classes derived from Statement
00969  */
00970 
00971 
00972 #if defined(_MSC_VER) && _MSC_VER <= 1200
00973 #pragma warning(disable:4786)
00974 #endif 
00975 
00976 /******************************************************************************
00977  * GotoStatement methods
00978  *****************************************************************************/
00979 
00980 /*==============================================================================
00981  * FUNCTION:        GotoStatement::GotoStatement
00982  * OVERVIEW:        Constructor.
00983  * PARAMETERS:      listStmt: a list of Statements (not the same as an RTL)
00984  *                    to serve as the initial list of statements
00985  * RETURNS:         N/a
00986  *============================================================================*/
00987 GotoStatement::GotoStatement()
00988   : pDest(NULL), m_isComputed(false) {
00989     kind = STMT_GOTO;
00990 }
00991 
00992 /*==============================================================================
00993  * FUNCTION:        GotoStatement::GotoStatement
00994  * OVERVIEW:        Construct a jump to a fixed address
00995  * PARAMETERS:      uDest: native address of destination
00996  * RETURNS:         N/a
00997  *============================================================================*/
00998 GotoStatement::GotoStatement(ADDRESS uDest) : m_isComputed(false) {
00999     kind = STMT_GOTO;
01000     pDest = new Const(uDest);
01001 }
01002 
01003 /*==============================================================================
01004  * FUNCTION:        GotoStatement::~GotoStatement
01005  * OVERVIEW:        Destructor
01006  * PARAMETERS:      None
01007  * RETURNS:         N/a
01008  *============================================================================*/
01009 GotoStatement::~GotoStatement() {
01010     if (pDest) ;//delete pDest;
01011 }
01012 
01013 /*==============================================================================
01014  * FUNCTION:        GotoStatement::getFixedDest
01015  * OVERVIEW:        Get the fixed destination of this CTI. Assumes destination
01016  *                  simplication has already been done so that a fixed dest will
01017  *                  be of the Exp form:
01018  *                     opIntConst dest
01019  * PARAMETERS:      <none>
01020  * RETURNS:         Fixed dest or NO_ADDRESS if there isn't one
01021  *============================================================================*/
01022 ADDRESS GotoStatement::getFixedDest() {
01023     if (pDest->getOper() != opIntConst) return NO_ADDRESS;
01024     return ((Const*)pDest)->getAddr();
01025 }
01026 
01027 /*==============================================================================
01028  * FUNCTION:        GotoStatement::setDest
01029  * OVERVIEW:        Set the destination of this jump to be a given expression.
01030  * PARAMETERS:      addr - the new fixed address
01031  * RETURNS:         Nothing
01032  *============================================================================*/
01033 void GotoStatement::setDest(Exp* pd) {
01034     pDest = pd;
01035 }
01036 
01037 /*==============================================================================
01038  * FUNCTION:        GotoStatement::setDest
01039  * OVERVIEW:        Set the destination of this jump to be a given fixed address.
01040  * PARAMETERS:      addr - the new fixed address
01041  * RETURNS:         <nothing>
01042  *============================================================================*/
01043 void GotoStatement::setDest(ADDRESS addr) {
01044 // This fails in FrontSparcTest, do you really want it to Mike? -trent
01045 //  assert(addr >= prog.limitTextLow && addr < prog.limitTextHigh);
01046     // Delete the old destination if there is one
01047     if (pDest != NULL)
01048         ;//delete pDest;
01049 
01050     pDest = new Const(addr);
01051 }
01052 
01053 /*==============================================================================
01054  * FUNCTION:        GotoStatement::getDest
01055  * OVERVIEW:        Returns the destination of this CTI.
01056  * PARAMETERS:      None
01057  * RETURNS:         Pointer to the SS representing the dest of this jump
01058  *============================================================================*/
01059 Exp* GotoStatement::getDest() {
01060     return pDest;
01061 }
01062 
01063 /*==============================================================================
01064  * FUNCTION:        GotoStatement::adjustFixedDest
01065  * OVERVIEW:        Adjust the destination of this CTI by a given amount. Causes
01066  *                  an error is this destination is not a fixed destination
01067  *                  (i.e. a constant offset).
01068  * PARAMETERS:      delta - the amount to add to the destination (can be
01069  *                  negative)
01070  * RETURNS:         <nothing>
01071  *============================================================================*/
01072 void GotoStatement::adjustFixedDest(int delta) {
01073     // Ensure that the destination is fixed.
01074     if (pDest == 0 || pDest->getOper() != opIntConst)
01075         LOG << "Can't adjust destination of non-static CTI\n";
01076 
01077     ADDRESS dest = ((Const*)pDest)->getAddr();
01078     ((Const*)pDest)->setAddr(dest + delta);
01079 }
01080 
01081 bool GotoStatement::search(Exp* search, Exp*& result) {
01082     result = NULL;
01083     if (pDest)
01084         return pDest->search(search, result);
01085     return false;
01086 }
01087 
01088 /*==============================================================================
01089  * FUNCTION:        GotoStatement::searchAndReplace
01090  * OVERVIEW:        Replace all instances of search with replace.
01091  * PARAMETERS:      search - a location to search for
01092  *                  replace - the expression with which to replace it
01093  *                  cc - ignored
01094  * RETURNS:         True if any change
01095  *============================================================================*/
01096 bool GotoStatement::searchAndReplace(Exp* search, Exp* replace, bool cc) {
01097     bool change = false;
01098     if (pDest) {
01099         pDest = pDest->searchReplaceAll(search, replace, change);
01100     }
01101     return change;
01102 }
01103 
01104 /*==============================================================================
01105  * FUNCTION:        GotoStatement::searchAll
01106  * OVERVIEW:        Find all instances of the search expression
01107  * PARAMETERS:      search - a location to search for
01108  *                  result - a list which will have any matching exprs
01109  *                           appended to it
01110  * RETURNS:         true if there were any matches
01111  *============================================================================*/
01112 bool GotoStatement::searchAll(Exp* search, std::list<Exp*> &result) {
01113     if (pDest)  return pDest->searchAll(search, result);
01114     return false;
01115 }
01116 
01117 /*==============================================================================
01118  * FUNCTION:        GotoStatement::print
01119  * OVERVIEW:        Display a text reprentation of this RTL to the given stream
01120  * NOTE:            Usually called from RTL::print, in which case the first 9
01121  *                    chars of the print have already been output to os
01122  * PARAMETERS:      os: stream to write to
01123  * RETURNS:         Nothing
01124  *============================================================================*/
01125 void GotoStatement::print(std::ostream& os, bool html) {
01126     os << std::setw(4) << std::dec << number << " ";
01127     if (html) {
01128         os << "</td><td>";
01129         os << "<a name=\"stmt" << std::dec << number << "\">";
01130     }
01131     os << "GOTO ";
01132     if (pDest == NULL)
01133         os << "*no dest*";
01134     else if (pDest->getOper() != opIntConst)
01135          pDest->print(os);
01136     else
01137         os << "0x" << std::hex << getFixedDest();
01138     if (html)
01139         os << "</a></td>";
01140 }
01141 
01142 /*==============================================================================
01143  * FUNCTION:      GotoStatement::setIsComputed
01144  * OVERVIEW:      Sets the fact that this call is computed.
01145  * NOTE:          This should really be removed, once CaseStatement and
01146  *                  HLNwayCall are implemented properly
01147  * PARAMETERS:    <none>
01148  * RETURNS:       <nothing>
01149  *============================================================================*/
01150 void GotoStatement::setIsComputed(bool b) {
01151     m_isComputed = b;
01152 }
01153 
01154 /*==============================================================================
01155  * FUNCTION:      GotoStatement::isComputed
01156  * OVERVIEW:      Returns whether or not this call is computed.
01157  * NOTE:          This should really be removed, once CaseStatement and HLNwayCall
01158  *                  are implemented properly
01159  * PARAMETERS:    <none>
01160  * RETURNS:       this call is computed
01161  *============================================================================*/
01162 bool GotoStatement::isComputed() {
01163     return m_isComputed;
01164 }
01165 
01166 /*==============================================================================
01167  * FUNCTION:        GotoStatement::clone
01168  * OVERVIEW:        Deep copy clone
01169  * PARAMETERS:      <none>
01170  * RETURNS:         Pointer to a new Statement, a clone of this GotoStatement
01171  *============================================================================*/
01172 Statement* GotoStatement::clone() {
01173     GotoStatement* ret = new GotoStatement();
01174     ret->pDest = pDest->clone();
01175     ret->m_isComputed = m_isComputed;
01176     // Statement members
01177     ret->pbb = pbb;
01178     ret->proc = proc;
01179     ret->number = number;
01180     return ret;
01181 }
01182 
01183 // visit this Statement in the RTL
01184 bool GotoStatement::accept(StmtVisitor* visitor) {
01185     return visitor->visit(this);
01186 }
01187 
01188 void GotoStatement::generateCode(HLLCode *hll, BasicBlock *pbb, int indLevel) {
01189     // dont generate any code for jumps, they will be handled by the BB
01190 }
01191 
01192 void GotoStatement::simplify() {
01193     if (isComputed()) {
01194         pDest = pDest->simplifyArith();
01195         pDest = pDest->simplify();
01196     }
01197 }
01198 
01199 /**********************************
01200  * BranchStatement methods
01201  **********************************/
01202 
01203 /*==============================================================================
01204  * FUNCTION:        BranchStatement::BranchStatement
01205  * OVERVIEW:        Constructor.
01206  * PARAMETERS:      None
01207  * RETURNS:         N/a
01208  *============================================================================*/
01209 BranchStatement::BranchStatement() : jtCond((BRANCH_TYPE)0), pCond(NULL), bFloat(false), size(0) {
01210     kind = STMT_BRANCH;
01211 }
01212 
01213 /*==============================================================================
01214  * FUNCTION:        BranchStatement::~BranchStatement
01215  * OVERVIEW:        Destructor
01216  * PARAMETERS:      None
01217  * RETURNS:         N/a
01218  *============================================================================*/
01219 BranchStatement::~BranchStatement() {
01220     if (pCond)
01221         ;//delete pCond;
01222 }
01223 
01224 /*==============================================================================
01225  * FUNCTION:        BranchStatement::setCondType
01226  * OVERVIEW:        Sets the BRANCH_TYPE of this jcond as well as the flag
01227  *                  indicating whether or not the floating point condition codes
01228  *                  are used.
01229  * PARAMETERS:      cond - the BRANCH_TYPE
01230  *                  usesFloat - this condional jump checks the floating point
01231  *                    condition codes
01232  * RETURNS:         a semantic string
01233  *============================================================================*/
01234 void BranchStatement::setCondType(BRANCH_TYPE cond, bool usesFloat /*= false*/) {
01235     jtCond = cond;
01236     bFloat = usesFloat;
01237 
01238     // set pCond to a high level representation of this type
01239     Exp* p = NULL;
01240     switch(cond) {
01241         case BRANCH_JE:
01242             p = new Binary(opEquals, new Terminal(opFlags), new Const(0));
01243             break;
01244         case BRANCH_JNE:
01245             p = new Binary(opNotEqual, new Terminal(opFlags), new Const(0));
01246             break;
01247         case BRANCH_JSL:
01248             p = new Binary(opLess, new Terminal(opFlags), new Const(0));
01249             break;
01250         case BRANCH_JSLE:
01251             p = new Binary(opLessEq, new Terminal(opFlags), new Const(0));
01252             break;
01253         case BRANCH_JSGE:
01254             p = new Binary(opGtrEq, new Terminal(opFlags), new Const(0));
01255             break;
01256         case BRANCH_JSG:
01257             p = new Binary(opGtr, new Terminal(opFlags), new Const(0));
01258             break;
01259         case BRANCH_JUL:
01260             p = new Binary(opLessUns, new Terminal(opFlags), new Const(0));
01261             break;
01262         case BRANCH_JULE:
01263             p = new Binary(opLessEqUns, new Terminal(opFlags), new Const(0));
01264             break;
01265         case BRANCH_JUGE:
01266             p = new Binary(opGtrEqUns, new Terminal(opFlags), new Const(0));
01267             break;
01268         case BRANCH_JUG:
01269             p = new Binary(opGtrUns, new Terminal(opFlags), new Const(0));
01270             break;
01271         case BRANCH_JMI:
01272             p = new Binary(opLess, new Terminal(opFlags), new Const(0));
01273             break;
01274         case BRANCH_JPOS:
01275             p = new Binary(opGtr, new Terminal(opFlags), new Const(0));
01276             break;
01277         case BRANCH_JOF:
01278             p = new Binary(opLessUns, new Terminal(opFlags), new Const(0));
01279             break;
01280         case BRANCH_JNOF:
01281             p = new Binary(opGtrUns, new Terminal(opFlags), new Const(0));
01282             break;
01283         case BRANCH_JPAR:
01284             // Can't handle this properly here; leave an impossible expression involving %flags so propagation will
01285             // still happen, and we can recognise this later in condToRelational()
01286             // Update: these expressions seem to get ignored ???
01287             p = new Binary(opEquals, new Terminal(opFlags), new Const(999));
01288             break;
01289     }
01290     // this is such a hack.. preferably we should actually recognise SUBFLAGS32(..,..,..) > 0 instead of just
01291     // SUBFLAGS32(..,..,..) but I'll leave this in here for the moment as it actually works.
01292     if (!Boomerang::get()->noDecompile)
01293         p = new Terminal(usesFloat ? opFflags : opFlags);
01294     assert(p);
01295     setCondExpr(p);
01296 }
01297 
01298 /*==============================================================================
01299  * FUNCTION:        BranchStatement::makeSigned
01300  * OVERVIEW:        Change this from an unsigned to a signed branch
01301  * PARAMETERS:      <none>
01302  * RETURNS:         <nothing>
01303  *============================================================================*/
01304 void BranchStatement::makeSigned() {
01305     // Make this into a signed branch
01306     switch (jtCond)
01307     {
01308         case BRANCH_JUL : jtCond = BRANCH_JSL;  break;
01309         case BRANCH_JULE: jtCond = BRANCH_JSLE; break;
01310         case BRANCH_JUGE: jtCond = BRANCH_JSGE; break;
01311         case BRANCH_JUG : jtCond = BRANCH_JSG;  break;
01312         default:
01313             // Do nothing for other cases
01314             break;
01315     }
01316 }
01317 
01318 /*==============================================================================
01319  * FUNCTION:        BranchStatement::getCondExpr
01320  * OVERVIEW:        Return the SemStr expression containing the HL condition.
01321  * PARAMETERS:      <none>
01322  * RETURNS:         ptr to an expression
01323  *============================================================================*/
01324 Exp* BranchStatement::getCondExpr() {
01325     return pCond;
01326 }
01327 
01328 /*==============================================================================
01329  * FUNCTION:        BranchStatement::setCondExpr
01330  * OVERVIEW:        Set the SemStr expression containing the HL condition.
01331  * PARAMETERS:      Pointer to Exp to set
01332  * RETURNS:         <nothing>
01333  *============================================================================*/
01334 void BranchStatement::setCondExpr(Exp* e) {
01335     if (pCond) ;//delete pCond;
01336     pCond = e;
01337 }
01338 
01339 PBB BranchStatement::getFallBB()
01340 {
01341     ADDRESS a = getFixedDest();
01342     if (a == NO_ADDRESS)
01343         return NULL;
01344     if (pbb == NULL)
01345         return NULL;
01346     if (pbb->getNumOutEdges() != 2)
01347         return NULL;
01348     if (pbb->getOutEdge(0)->getLowAddr() == a)
01349         return pbb->getOutEdge(1);
01350     return pbb->getOutEdge(0);
01351 }
01352 
01353 // not that if you set the taken BB or fixed dest first, you will not be able to set the fall BB
01354 void BranchStatement::setFallBB(PBB bb)
01355 {
01356     ADDRESS a = getFixedDest();
01357     if (a == NO_ADDRESS)
01358         return;
01359     if (pbb == NULL)
01360         return;
01361     if (pbb->getNumOutEdges() != 2)
01362         return;
01363     if (pbb->getOutEdge(0)->getLowAddr() == a) {
01364         pbb->getOutEdge(1)->deleteInEdge(pbb);
01365         pbb->setOutEdge(1, bb);
01366         bb->addInEdge(pbb);
01367     } else {
01368         pbb->getOutEdge(0)->deleteInEdge(pbb);
01369         pbb->setOutEdge(0, bb);
01370         bb->addInEdge(pbb);
01371     }
01372 }
01373 
01374 PBB BranchStatement::getTakenBB()
01375 {
01376     ADDRESS a = getFixedDest();
01377     if (a == NO_ADDRESS)
01378         return NULL;
01379     if (pbb == NULL)
01380         return NULL;
01381     if (pbb->getNumOutEdges() != 2)
01382         return NULL;
01383     if (pbb->getOutEdge(0)->getLowAddr() == a)
01384         return pbb->getOutEdge(0);
01385     return pbb->getOutEdge(1);
01386 }
01387 
01388 void BranchStatement::setTakenBB(PBB bb)
01389 {
01390     ADDRESS a = getFixedDest();
01391     if (a == NO_ADDRESS)
01392         return;
01393     if (pbb == NULL)
01394         return;
01395     if (pbb->getNumOutEdges() != 2)
01396         return;
01397     if (pbb->getOutEdge(0)->getLowAddr() == a) {
01398         pbb->getOutEdge(0)->deleteInEdge(pbb);
01399         pbb->setOutEdge(0, bb);
01400         bb->addInEdge(pbb);
01401     } else {
01402         pbb->getOutEdge(1)->deleteInEdge(pbb);
01403         pbb->setOutEdge(1, bb);
01404         bb->addInEdge(pbb);
01405     }
01406 }
01407 
01408 bool BranchStatement::search(Exp* search, Exp*& result) {
01409     if (pCond) return pCond->search(search, result);
01410     result = NULL;
01411     return false;
01412 }
01413 
01414 /*==============================================================================
01415  * FUNCTION:        BranchStatement::searchAndReplace
01416  * OVERVIEW:        Replace all instances of search with replace.
01417  * PARAMETERS:      search - a location to search for
01418  *                  replace - the expression with which to replace it
01419  *                  cc - ignored
01420  * RETURNS:         True if any change
01421  *============================================================================*/
01422 bool BranchStatement::searchAndReplace(Exp* search, Exp* replace, bool cc) {
01423     GotoStatement::searchAndReplace(search, replace, cc);
01424     bool change = false;
01425     if (pCond)
01426         pCond = pCond->searchReplaceAll(search, replace, change);
01427     return change;
01428 }
01429 
01430 /*==============================================================================
01431  * FUNCTION:        BranchStatement::searchAll
01432  * OVERVIEW:        Find all instances of the search expression
01433  * PARAMETERS:      search - a location to search for
01434  *                  result - a list which will have any matching exprs
01435  *                           appended to it
01436  * RETURNS:         true if there were any matches
01437  *============================================================================*/
01438 bool BranchStatement::searchAll(Exp* search, std::list<Exp*> &result) {
01439     if (pCond) return pCond->searchAll(search, result);
01440     return false;
01441 }
01442 
01443 
01444 /*==============================================================================
01445  * FUNCTION:        BranchStatement::print
01446  * OVERVIEW:        Write a text representation to the given stream
01447  * PARAMETERS:      os: stream
01448  * RETURNS:         Nothing
01449  *============================================================================*/
01450 void BranchStatement::print(std::ostream& os, bool html) {
01451     os << std::setw(4) << std::dec << number << " ";
01452     if (html) {
01453         os << "</td><td>";
01454         os << "<a name=\"stmt" << std::dec << number << "\">";
01455     }
01456     os << "BRANCH ";
01457     if (pDest == NULL)
01458         os << "*no dest*";
01459     else if (!pDest->isIntConst())
01460         os << pDest;
01461     else {
01462         // Really we'd like to display the destination label here...
01463         os << "0x" << std::hex << getFixedDest();
01464     }
01465     os << ", condition ";
01466     switch (jtCond) {
01467         case BRANCH_JE:    os << "equals"; break;
01468         case BRANCH_JNE:   os << "not equals"; break;
01469         case BRANCH_JSL:   os << "signed less"; break;
01470         case BRANCH_JSLE:  os << "signed less or equals"; break;
01471         case BRANCH_JSGE:  os << "signed greater or equals"; break;
01472         case BRANCH_JSG:   os << "signed greater"; break;
01473         case BRANCH_JUL:   os << "unsigned less"; break;
01474         case BRANCH_JULE:  os << "unsigned less or equals"; break;
01475         case BRANCH_JUGE:  os << "unsigned greater or equals"; break;
01476         case BRANCH_JUG:   os << "unsigned greater"; break;
01477         case BRANCH_JMI:   os << "minus"; break;
01478         case BRANCH_JPOS:  os << "plus"; break;
01479         case BRANCH_JOF:   os << "overflow"; break;
01480         case BRANCH_JNOF:  os << "no overflow"; break;
01481         case BRANCH_JPAR:  os << "parity"; break;
01482     }
01483     if (bFloat) os << " float";
01484     os << std::endl;
01485     if (pCond) {
01486         if (html)
01487             os << "<br>";
01488         os << "High level: ";
01489         pCond->print(os, html);
01490     }
01491     if (html)
01492         os << "</a></td>";
01493 }
01494 
01495 /*==============================================================================
01496  * FUNCTION:        BranchStatement::clone
01497  * OVERVIEW:        Deep copy clone
01498  * PARAMETERS:      <none>
01499  * RETURNS:         Pointer to a new Statement, a clone of this BranchStatement
01500  *============================================================================*/
01501 Statement* BranchStatement::clone() {
01502     BranchStatement* ret = new BranchStatement();
01503     ret->pDest = pDest->clone();
01504     ret->m_isComputed = m_isComputed;
01505     ret->jtCond = jtCond;
01506     if (pCond) ret->pCond = pCond->clone();
01507     else ret->pCond = NULL;
01508     ret->bFloat = bFloat;
01509     // Statement members
01510     ret->pbb = pbb;
01511     ret->proc = proc;
01512     ret->number = number;
01513     return ret;
01514 }
01515 
01516 // visit this stmt
01517 bool BranchStatement::accept(StmtVisitor* visitor) {
01518     return visitor->visit(this);
01519 }
01520 
01521 void BranchStatement::generateCode(HLLCode *hll, BasicBlock *pbb, int indLevel) {
01522     // dont generate any code for jconds, they will be handled by the bb
01523 }
01524 
01525 bool BranchStatement::usesExp(Exp *e) {
01526     Exp *tmp;
01527     return pCond && pCond->search(e, tmp);
01528 }
01529 
01530 
01531 // Common to BranchStatement and BoolAssign
01532 // Return true if this is now a floating point Branch
01533 bool condToRelational(Exp*& pCond, BRANCH_TYPE jtCond) {
01534     pCond = pCond->simplifyArith()->simplify();
01535 
01536     std::stringstream os;
01537     pCond->print(os);
01538     std::string s = os.str();
01539 
01540     OPER condOp = pCond->getOper();
01541     if (condOp == opFlagCall && strncmp(((Const*)pCond->getSubExp1())->getStr(), "SUBFLAGS", 8) == 0) {
01542         OPER op = opWild;
01543         // Special for PPC unsigned compares; may be other cases in the future
01544         bool makeUns = strncmp(((Const*)pCond->getSubExp1())->getStr(), "SUBFLAGSNL", 10) == 0;
01545         switch (jtCond) {
01546             case BRANCH_JE:    op = opEquals; break;
01547             case BRANCH_JNE:   op = opNotEqual; break;
01548             case BRANCH_JSL:   if (makeUns) op = opLessUns; else op = opLess; break;
01549             case BRANCH_JSLE:  if (makeUns) op = opLessEqUns; else op = opLessEq; break;
01550             case BRANCH_JSGE:  if (makeUns) op = opGtrEqUns; else op = opGtrEq; break;
01551             case BRANCH_JSG:   if (makeUns) op = opGtrUns; else op = opGtr; break;
01552             case BRANCH_JUL:   op = opLessUns; break;
01553             case BRANCH_JULE:  op = opLessEqUns; break;
01554             case BRANCH_JUGE:  op = opGtrEqUns; break;
01555             case BRANCH_JUG:   op = opGtrUns; break;
01556             case BRANCH_JMI:
01557                 /*   pCond
01558                      /    \
01559                 Const      opList
01560                 "SUBFLAGS"  /   \
01561                            P1   opList
01562                                  /   \
01563                                 P2  opList
01564                                      /   \
01565                                     P3   opNil */
01566                 pCond = new Binary(opLess,          // P3 < 0
01567                     pCond->getSubExp2()->getSubExp2()->getSubExp2()->getSubExp1()->clone(),
01568                     new Const(0));
01569                 break;
01570             case BRANCH_JPOS:
01571                 pCond = new Binary(opGtrEq,         // P3 >= 0
01572                     pCond->getSubExp2()->getSubExp2()->getSubExp2()->getSubExp1()->clone(),
01573                     new Const(0));
01574                 break;
01575             case BRANCH_JOF:
01576             case BRANCH_JNOF:
01577             case BRANCH_JPAR:
01578                 break;
01579         }
01580         if (op != opWild) {
01581             pCond = new Binary(op,
01582                 pCond->getSubExp2()->getSubExp1()->clone(),                 // P1
01583                 pCond->getSubExp2()->getSubExp2()->getSubExp1()->clone());  // P2
01584         }
01585     }
01586     else if (condOp == opFlagCall && strncmp(((Const*)pCond->getSubExp1())->getStr(), "LOGICALFLAGS", 12) == 0) {
01587         // Exp *e = pCond;
01588         OPER op = opWild;
01589         switch (jtCond) {
01590             case BRANCH_JE:   op = opEquals; break;
01591             case BRANCH_JNE:  op = opNotEqual; break;
01592             case BRANCH_JMI:  op = opLess; break;
01593             case BRANCH_JPOS: op = opGtrEq; break;
01594             // FIXME: This next set is quite shakey. Really, we should pull all the individual flag definitions out of
01595             // the flag definitions, and substitute these into the equivalent conditions for the branches (a big, ugly
01596             // job).
01597             case BRANCH_JSL:  op = opLess; break;
01598             case BRANCH_JSLE: op = opLessEq; break;
01599             case BRANCH_JSGE: op = opGtrEq; break;
01600             case BRANCH_JSG:  op = opGtr; break;
01601             // These next few seem to fluke working fine on architectures like X86, SPARC, and 68K which clear the
01602             // carry on all logical operations.
01603             case BRANCH_JUL:  op = opLessUns; break;    // NOTE: this is equivalent to never branching, since nothing
01604                                                         // can be unsigned less than zero
01605             case BRANCH_JULE: op = opLessEqUns; break;
01606             case BRANCH_JUGE: op = opGtrEqUns; break;   // Similarly, this is equivalent to always branching
01607             case BRANCH_JUG:  op = opGtrUns; break;
01608             case BRANCH_JPAR: {
01609                 // This is pentium specific too; see below for more notes.
01610                 /*                  pCond
01611                                     /   \
01612                               Const     opList
01613                     "LOGICALFLAGS8"     /   \
01614                                 opBitAnd    opNil
01615                                 /       \
01616                         opFlagCall      opIntConst
01617                         /       \           mask
01618                     Const       opList
01619                 "SETFFLAGS"     /   \
01620                                P1   opList
01621                                     /   \
01622                                     P2  opNil
01623                 */
01624                 Exp* flagsParam = ((Binary*)((Binary*)pCond)->getSubExp2())->getSubExp1();
01625                 Exp* test = flagsParam;
01626                 if (test->isSubscript())
01627                     test = ((RefExp*)test)->getSubExp1();
01628                 if (test->isTemp())
01629                     return false;           // Just not propagated yet
01630                 int mask = 0;
01631                 if (flagsParam->getOper() == opBitAnd) {
01632                     Exp* setFlagsParam = ((Binary*)flagsParam)->getSubExp2();
01633                     if (setFlagsParam->isIntConst())
01634                         mask = ((Const*)setFlagsParam)->getInt();
01635                 }
01636                 // Sometimes the mask includes the 0x4 bit, but we expect that to be off all the time. So effectively
01637                 // the branch is for any one of the (one or two) bits being on. For example, if the mask is 0x41, we
01638                 // are branching of less (0x1) or equal (0x41).
01639                 mask &= 0x41;
01640                 OPER op;
01641                 switch (mask) {
01642                     case 0:
01643                         LOG << "WARNING: unhandled pentium branch if parity with pCond = " << pCond << "\n";
01644                         return false;
01645                     case 1:
01646                         op = opLess;
01647                         break;
01648                     case 0x40:
01649                         op = opEquals;
01650                         break;
01651                     case 0x41:
01652                         op = opLessEq;
01653                         break;
01654                     default:
01655                         op = opWild;        // Not possible, but avoid a compiler warning
01656                         break;
01657                 }
01658                 pCond = new Binary(op,
01659                     flagsParam->getSubExp1()->getSubExp2()->getSubExp1()->clone(),
01660                     flagsParam->getSubExp1()->getSubExp2()->getSubExp2()->getSubExp1() ->clone());
01661                     return true;            // This is a floating point comparison
01662                 }
01663             default:
01664                 break;
01665         }
01666         if (op != opWild) {
01667             pCond = new Binary(op,
01668                 pCond->getSubExp2()->getSubExp1()->clone(),
01669                 new Const(0));
01670         }
01671     }
01672     else if (condOp == opFlagCall && strncmp(((Const*)pCond->getSubExp1())->getStr(), "SETFFLAGS", 9) == 0) {
01673         // Exp *e = pCond;
01674         OPER op = opWild;
01675         switch (jtCond) {
01676             case BRANCH_JE:   op = opEquals; break;
01677             case BRANCH_JNE:  op = opNotEqual; break;
01678             case BRANCH_JMI:  op = opLess; break;
01679             case BRANCH_JPOS: op = opGtrEq; break;
01680             case BRANCH_JSL:  op = opLess; break;
01681             case BRANCH_JSLE: op = opLessEq; break;
01682             case BRANCH_JSGE: op = opGtrEq; break;
01683             case BRANCH_JSG:  op = opGtr; break;
01684             default:
01685                 break;
01686         }
01687         if (op != opWild) {
01688             pCond = new Binary(op,
01689                 pCond->getSubExp2()->getSubExp1()->clone(),
01690                 pCond->getSubExp2()->getSubExp2()->getSubExp1() ->clone());
01691         }
01692     }
01693     // ICK! This is all PENTIUM SPECIFIC... needs to go somewhere else.
01694     // Might be of the form (SETFFLAGS(...) & MASK) RELOP INTCONST where MASK could be a combination of 1, 4, and 40,
01695     // and relop could be == or ~=.  There could also be an XOR 40h after the AND
01696     // From MSVC 6, we can also see MASK = 0x44, 0x41, 0x5 followed by jump if (even) parity (see above)
01697     // %fflags = 0..0.0 00 >
01698     // %fflags = 0..0.1 01 <
01699     // %fflags = 1..0.0 40 =
01700     // %fflags = 1..1.1 45 not comparable
01701     // Example: (SETTFLAGS(...) & 1) ~= 0
01702     // left = SETFFLAGS(...) & 1
01703     // left1 = SETFFLAGS(...) left2 = int 1, k = 0, mask = 1
01704     else if (condOp == opEquals || condOp == opNotEqual) {
01705         Exp* left =  ((Binary*)pCond)->getSubExp1();
01706         Exp* right = ((Binary*)pCond)->getSubExp2();
01707         bool hasXor40 = false;
01708         if (left->getOper() == opBitXor && right->isIntConst()) {
01709             Exp* r2 = ((Binary*)left)->getSubExp2();
01710             if (r2->isIntConst()) {
01711                 int k2 = ((Const*)r2)->getInt();
01712                 if (k2 == 0x40) {
01713                     hasXor40 = true;
01714                     left = ((Binary*)left)->getSubExp1();
01715                 }
01716             }
01717         }
01718         if (left->getOper() == opBitAnd && right->isIntConst()) {
01719             Exp* left1 = ((Binary*)left)->getSubExp1();
01720             Exp* left2 = ((Binary*)left)->getSubExp2();
01721             int k = ((Const*)right)->getInt();
01722             // Only interested in 40, 1
01723             k &= 0x41;
01724             if (left1->getOper() == opFlagCall && left2->isIntConst()) {
01725                 int mask = ((Const*)left2)->getInt();
01726                 // Only interested in 1, 40
01727                 mask &= 0x41;
01728                 OPER op = opWild;
01729                 if (hasXor40) {
01730                     assert(k == 0);
01731                     op = condOp;
01732                 } else {
01733                     switch (mask) {
01734                         case 1:
01735                             if (condOp == opEquals && k == 0 || condOp == opNotEqual && k == 1)
01736                                     op = opGtrEq;
01737                             else
01738                                     op = opLess;
01739                             break;
01740                         case 0x40:
01741                             if (condOp == opEquals && k == 0 || condOp == opNotEqual && k == 0x40)
01742                                     op = opNotEqual;
01743                             else
01744                                     op = opEquals;
01745                             break;
01746                         case 0x41:
01747                             switch (k) {
01748                                 case 0:
01749                                     if (condOp == opEquals) op = opGtr;
01750                                     else op = opLessEq;
01751                                     break;
01752                                 case 1:
01753                                     if (condOp == opEquals) op = opLess;
01754                                     else op = opGtrEq;
01755                                     break;
01756                                 case 0x40:
01757                                     if (condOp == opEquals) op = opEquals;
01758                                     else op = opNotEqual;
01759                                     break;
01760                                 default:
01761                                     std::cerr << "BranchStatement::simplify: k is " << std::hex << k << "\n";
01762                                     assert(0);
01763                             }
01764                             break;
01765                         default:
01766                             std::cerr << "BranchStatement::simplify: Mask is " << std::hex << mask << "\n";
01767                             assert(0);
01768                     }
01769                 }
01770                 if (op != opWild) {
01771                     pCond = new Binary(op,
01772                         left1->getSubExp2()->getSubExp1(),
01773                         left1->getSubExp2()->getSubExp2()->getSubExp1());
01774                     return true;      // This is now a float comparison
01775                 }
01776             }
01777         }
01778     }
01779     return false;
01780 }
01781 
01782 
01783 void BranchStatement::simplify() {
01784     if (pCond) {
01785         if (condToRelational(pCond, jtCond))
01786             bFloat = true;
01787     }
01788 }
01789 
01790 /**********************************
01791  * CaseStatement methods
01792  **********************************/
01793 /*==============================================================================
01794  * FUNCTION:        CaseStatement::CaseStatement
01795  * OVERVIEW:        Constructor.
01796  * PARAMETERS:      None
01797  * RETURNS:         N/a
01798  *============================================================================*/
01799 CaseStatement::CaseStatement() :
01800     pSwitchInfo(NULL) {
01801     kind = STMT_CASE;
01802 }
01803 
01804 /*==============================================================================
01805  * FUNCTION:        CaseStatement::~CaseStatement
01806  * OVERVIEW:        Destructor
01807  * NOTE:            Don't delete the pSwitchVar; it's always a copy of something else (so don't delete twice)
01808  * PARAMETERS:      None
01809  * RETURNS:         N/a
01810  *============================================================================*/
01811 CaseStatement::~CaseStatement() {
01812     if (pSwitchInfo)
01813         ;//delete pSwitchInfo;
01814 }
01815 
01816 /*==============================================================================
01817  * FUNCTION:        CaseStatement::getSwitchInfo
01818  * OVERVIEW:        Return a pointer to a struct with switch information in it
01819  * PARAMETERS:      <none>
01820  * RETURNS:         a semantic string
01821  *============================================================================*/
01822 SWITCH_INFO* CaseStatement::getSwitchInfo() {
01823     return pSwitchInfo;
01824 }
01825 
01826 /*==============================================================================
01827  * FUNCTION:        CaseStatement::setSwitchInfo
01828  * OVERVIEW:        Set a pointer to a SWITCH_INFO struct
01829  * PARAMETERS:      Pointer to SWITCH_INFO struct
01830  * RETURNS:         <nothing>
01831  *============================================================================*/
01832 void CaseStatement::setSwitchInfo(SWITCH_INFO* psi) {
01833     pSwitchInfo = psi;
01834 }
01835 
01836 /*==============================================================================
01837  * FUNCTION:        CaseStatement::searchAndReplace
01838  * OVERVIEW:        Replace all instances of search with replace.
01839  * PARAMETERS:      search - a location to search for
01840  *                  replace - the expression with which to replace it
01841  *                  cc - ignored
01842  * RETURNS:         True if any change
01843  *============================================================================*/
01844 bool CaseStatement::searchAndReplace(Exp* search, Exp* replace, bool cc) {
01845     bool ch = GotoStatement::searchAndReplace(search, replace, cc);
01846     bool ch2 = false;
01847     if (pSwitchInfo && pSwitchInfo->pSwitchVar)
01848         pSwitchInfo->pSwitchVar = pSwitchInfo->pSwitchVar->searchReplaceAll(search, replace, ch2);
01849     return ch | ch2;
01850 }
01851 
01852 /*==============================================================================
01853  * FUNCTION:        CaseStatement::searchAll
01854  * OVERVIEW:        Find all instances of the search expression
01855  * PARAMETERS:      search - a location to search for
01856  *                  result - a list which will have any matching exprs appended to it
01857  * NOTES:           search can't easily be made const
01858  * RETURNS:         true if there were any matches
01859  *============================================================================*/
01860 bool CaseStatement::searchAll(Exp* search, std::list<Exp*> &result) {
01861     return GotoStatement::searchAll(search, result) ||
01862         ( pSwitchInfo && pSwitchInfo->pSwitchVar && pSwitchInfo->pSwitchVar->searchAll(search, result) );
01863 }
01864 
01865 /*==============================================================================
01866  * FUNCTION:        CaseStatement::print
01867  * OVERVIEW:        Write a text representation to the given stream
01868  * PARAMETERS:      os: stream
01869  *                  indent: number of columns to skip
01870  * RETURNS:         Nothing
01871  *============================================================================*/
01872 void CaseStatement::print(std::ostream& os, bool html) {
01873     os << std::setw(4) << std::dec << number << " ";
01874     if (html) {
01875         os << "</td><td>";
01876         os << "<a name=\"stmt" << std::dec << number << "\">";
01877     }
01878     if (pSwitchInfo == NULL) {
01879         os << "CASE [";
01880         if (pDest == NULL)
01881             os << "*no dest*";
01882         else os << pDest;
01883         os << "]";
01884     } else
01885         os << "SWITCH(" << pSwitchInfo->pSwitchVar << ")\n";
01886     if (html)
01887         os << "</a></td>";
01888 }
01889 
01890 
01891 /*==============================================================================
01892  * FUNCTION:        CaseStatement::clone
01893  * OVERVIEW:        Deep copy clone
01894  * PARAMETERS:      <none>
01895  * RETURNS:         Pointer to a new Statement that is a clone of this one
01896  *============================================================================*/
01897 Statement* CaseStatement::clone() {
01898     CaseStatement* ret = new CaseStatement();
01899     ret->pDest = pDest->clone();
01900     ret->m_isComputed = m_isComputed;
01901     ret->pSwitchInfo = new SWITCH_INFO;
01902     *ret->pSwitchInfo = *pSwitchInfo;
01903     ret->pSwitchInfo->pSwitchVar = pSwitchInfo->pSwitchVar->clone();
01904     // Statement members
01905     ret->pbb = pbb;
01906     ret->proc = proc;
01907     ret->number = number;
01908     return ret;
01909 }
01910 
01911 // visit this stmt
01912 bool CaseStatement::accept(StmtVisitor* visitor) {
01913     return visitor->visit(this);
01914 }
01915 
01916 void CaseStatement::generateCode(HLLCode *hll, BasicBlock *pbb, int indLevel) {
01917     // dont generate any code for switches, they will be handled by the bb
01918 }
01919 
01920 bool CaseStatement::usesExp(Exp *e) {
01921     // Before a switch statement is recognised, pDest is non null
01922     if (pDest)
01923         return *pDest == *e;
01924     // After a switch statement is recognised, pDest is null, and pSwitchInfo->pSwitchVar takes over
01925     if (pSwitchInfo->pSwitchVar)
01926         return *pSwitchInfo->pSwitchVar == *e;
01927     return false;
01928 }
01929 
01930 
01931 void CaseStatement::simplify() {
01932     if (pDest)
01933         pDest = pDest->simplify();
01934     else if (pSwitchInfo && pSwitchInfo->pSwitchVar)
01935         pSwitchInfo->pSwitchVar = pSwitchInfo->pSwitchVar->simplify();
01936 }
01937 
01938 /**********************************
01939  *      CallStatement methods
01940  **********************************/
01941 
01942 /*==============================================================================
01943  * FUNCTION:         CallStatement::CallStatement
01944  * OVERVIEW:         Constructor for a call
01945  * PARAMETERS:       None
01946  * RETURNS:          <nothing>
01947  *============================================================================*/
01948 CallStatement::CallStatement(): returnAfterCall(false), calleeReturn(NULL) {
01949     kind = STMT_CALL;
01950     procDest = NULL;
01951     signature = NULL;
01952 }
01953 
01954 /*==============================================================================
01955  * FUNCTION:      CallStatement::~CallStatement
01956  * OVERVIEW:      Destructor
01957  * PARAMETERS:    BB - the enclosing basic block of this call
01958  * RETURNS:       <nothing>
01959  *============================================================================*/
01960 CallStatement::~CallStatement() {
01961 }
01962 
01963 // Temporarily needed for ad-hoc type analysis
01964 int CallStatement::findDefine(Exp *e) {
01965     StatementList::iterator rr;
01966     int i = 0;
01967     for (rr = defines.begin(); rr != defines.end(); ++rr, ++i) {
01968         Exp* ret = ((Assignment*)*rr)->getLeft();
01969         if (*ret == *e)
01970             return i;
01971     }
01972     return -1;
01973 }
01974 
01975 Exp *CallStatement::getProven(Exp *e) {
01976     if (procDest)
01977         return procDest->getProven(e);
01978     return NULL;
01979 }
01980 
01981 // Localise only components of e, i.e. xxx if e is m[xxx]
01982 void CallStatement::localiseComp(Exp* e) {
01983     if (e->isMemOf()) {
01984         ((Location*)e)->setSubExp1(localiseExp(((Location*)e)->getSubExp1()));
01985     }
01986 }
01987 // Substitute the various components of expression e with the appropriate reaching definitions.
01988 // Used in e.g. fixCallBypass (via the CallBypasser). Locations defined in this call are replaced with their proven
01989 // values, which are in terms of the initial values at the start of the call (reaching definitions at the call)
01990 Exp* CallStatement::localiseExp(Exp* e) {
01991     if (!defCol.isInitialised()) return e;              // Don't attempt to subscript if the data flow not started yet
01992     Localiser l(this);
01993     e = e->clone()->accept(&l);
01994 
01995     return e;
01996 }
01997 
01998 // Find the definition for the given expression, using the embedded Collector object
01999 // Was called findArgument(), and used implicit arguments and signature parameters
02000 // Note: must only operator on unsubscripted locations, otherwise it is invalid
02001 Exp* CallStatement::findDefFor(Exp *e) {
02002     return defCol.findDefFor(e);
02003 }
02004 
02005 Type *CallStatement::getArgumentType(int i) {
02006     assert(i < (int)arguments.size());
02007     StatementList::iterator aa = arguments.begin();
02008     my_advance(aa, i);  
02009     return ((Assign*)(*aa))->getType();
02010 }
02011 
02012 /*==============================================================================
02013  * FUNCTION:      CallStatement::setArguments
02014  * OVERVIEW:      Set the arguments of this call.
02015  * PARAMETERS:    arguments - the list of locations to set the arguments to (for testing)
02016  * RETURNS:       <nothing>
02017  *============================================================================*/
02018 void CallStatement::setArguments(StatementList& args) {
02019     arguments.clear();
02020     arguments.append(args);
02021     StatementList::iterator ll;
02022     for (ll = arguments.begin(); ll != arguments.end(); ++ll) {
02023         ((Assign*)*ll)->setProc(proc);
02024         ((Assign*)*ll)->setBB(pbb);
02025     }
02026 }
02027 
02028 /*==============================================================================
02029  * FUNCTION:      CallStatement::setSigArguments
02030  * OVERVIEW:      Set the arguments of this call based on signature info
02031  * NOTE:          Should only be called for calls to library functions
02032  * PARAMETERS:    None
02033  * RETURNS:       <nothing>
02034  *============================================================================*/
02035 void CallStatement::setSigArguments() {
02036     if (signature) return;              // Already done
02037     if (procDest == NULL)
02038         // FIXME: Need to check this
02039         return;
02040     // Clone here because each call to procDest could have a different signature, modified by ellipsisProcessing
02041     signature = procDest->getSignature()->clone();
02042     procDest->addCaller(this);
02043 
02044     if (!procDest->isLib())
02045         return;             // Using dataflow analysis now
02046     int n = signature->getNumParams();
02047     int i;
02048     arguments.clear();
02049     for (i = 0; i < n; i++) {
02050         Exp *e = signature->getArgumentExp(i);
02051         assert(e);
02052         Location *l = dynamic_cast<Location*>(e);
02053         if (l) {
02054             l->setProc(proc);       // Needed?
02055         }
02056         Assign* as = new Assign(signature->getParamType(i)->clone(), e->clone(), e->clone());
02057         as->setProc(proc);
02058         as->setBB(pbb);
02059         as->setNumber(number);      // So fromSSAform will work later. But note: this call is probably not numbered yet!
02060         as->setParent(this);
02061         arguments.append(as);
02062     }
02063 
02064     // initialize returns
02065     // FIXME: anything needed here?
02066 }
02067 
02068 bool CallStatement::search(Exp* search, Exp*& result) {
02069     bool found = GotoStatement::search(search, result);
02070     if (found) return true;
02071     StatementList::iterator ss;
02072     for (ss = defines.begin(); ss != defines.end(); ++ss) {
02073         if ((*ss)->search(search, result))
02074             return true;
02075     }
02076     for (ss = arguments.begin(); ss != arguments.end(); ++ss) {
02077         if ((*ss)->search(search, result))
02078             return true;
02079     }
02080     return false;
02081 }
02082 
02083 /*==============================================================================
02084  * FUNCTION:        CallStatement::searchAndReplace
02085  * OVERVIEW:        Replace all instances of search with replace.
02086  * PARAMETERS:      search - a location to search for
02087  *                  replace - the expression with which to replace it
02088  *                  cc - true to replace in collectors
02089  * RETURNS:         True if any change
02090  *============================================================================*/
02091 bool CallStatement::searchAndReplace(Exp* search, Exp* replace, bool cc) {
02092     bool change = GotoStatement::searchAndReplace(search, replace, cc);
02093     StatementList::iterator ss;
02094     // FIXME: MVE: Check if we ever want to change the LHS of arguments or defines...
02095     for (ss = defines.begin(); ss != defines.end(); ++ss)
02096         change |= (*ss)->searchAndReplace(search, replace, cc);
02097     for (ss = arguments.begin(); ss != arguments.end(); ++ss)
02098         change |= (*ss)->searchAndReplace(search, replace, cc);
02099     if (cc) {
02100         DefCollector::iterator dd;
02101         for (dd = defCol.begin(); dd != defCol.end(); ++dd)
02102             change |= (*dd)->searchAndReplace(search, replace, cc);
02103     }
02104     return change;
02105 }
02106 
02107 /*==============================================================================
02108  * FUNCTION:        CallStatement::searchAll
02109  * OVERVIEW:        Find all instances of the search expression
02110  * PARAMETERS:      search - a location to search for
02111  *                  result - a list which will have any matching exprs appended to it
02112  * RETURNS:         true if there were any matches
02113  *============================================================================*/
02114 bool CallStatement::searchAll(Exp* search, std::list<Exp *>& result) {
02115     bool found = GotoStatement::searchAll(search, result);
02116     StatementList::iterator ss;
02117     for (ss = defines.begin(); ss != defines.end(); ++ss) {
02118         if ((*ss)->searchAll(search, result))
02119             found = true;
02120     }
02121     for (ss = arguments.begin(); ss != arguments.end(); ++ss) {
02122         if ((*ss)->searchAll(search, result))
02123             found = true;
02124     }
02125     return found;
02126 }
02127 
02128 /*==============================================================================
02129  * FUNCTION:        CallStatement::print
02130  * OVERVIEW:        Write a text representation of this RTL to the given stream
02131  * PARAMETERS:      os: stream to write to
02132  * RETURNS:         Nothing
02133  *============================================================================*/
02134 void CallStatement::print(std::ostream& os, bool html) {
02135     os << std::setw(4) << std::dec << number << " ";
02136     if (html) {
02137         os << "</td><td>";
02138         os << "<a name=\"stmt" << std::dec << number << "\">";
02139     }
02140 
02141     // Define(s), if any
02142     if (defines.size()) {
02143         if (defines.size() > 1) os << "{";
02144         StatementList::iterator rr;
02145         bool first = true;
02146         for (rr = defines.begin(); rr != defines.end(); ++rr) {
02147             assert((*rr)->isAssignment());
02148             Assignment *as = (Assignment*)*rr;
02149             if (first)
02150                 first = false;
02151             else
02152                 os << ", ";
02153             os << "*" << as->getType() << "* " << as->getLeft();
02154             if (as->isAssign())
02155                 os << " := " << ((Assign*)as)->getRight();
02156         }
02157         if (defines.size() > 1) os << "}";
02158         os << " := ";
02159     } else if (isChildless()) {
02160         if (html)
02161             os << "&lt;all&gt; := ";
02162         else
02163             os << "<all> := ";
02164     }
02165 
02166     os << "CALL ";
02167     if (procDest)
02168         os << procDest->getName();
02169     else if (pDest == NULL)
02170             os << "*no dest*";
02171     else {
02172         if (pDest->isIntConst())
02173             os << "0x" << std::hex << ((Const*)pDest)->getInt();
02174         else
02175             pDest->print(os, html);     // Could still be an expression
02176     }
02177 
02178     // Print the actual arguments of the call
02179     if (isChildless()) {
02180         if (html)
02181             os << "(&lt;all&gt;)";
02182         else
02183             os << "(<all>)";
02184     } else {
02185         os << "(\n";
02186         StatementList::iterator aa;
02187         for (aa = arguments.begin(); aa != arguments.end(); ++aa) {
02188             os << "                ";
02189             ((Assignment*)*aa)->printCompact(os, html);
02190             os << "\n";
02191         }
02192         os << "              )";
02193     }
02194 
02195 #if 1
02196     // Collected reaching definitions
02197     if (html)
02198         os << "<br>";
02199     else 
02200         os << "\n              ";
02201     os << "Reaching definitions: ";
02202     defCol.print(os, html);
02203     if (html)
02204         os << "<br>";
02205     else
02206         os << "\n              ";
02207     os << "Live variables: ";
02208     useCol.print(os, html);
02209 #endif
02210 
02211     if (html)
02212         os << "</a></td>";
02213 }
02214 
02215 /*==============================================================================
02216  * FUNCTION:         CallStatement::setReturnAfterCall
02217  * OVERVIEW:         Sets a bit that says that this call is effectively followed by a return. This happens e.g. on
02218  *                      Sparc when there is a restore in the delay slot of the call
02219  * PARAMETERS:       b: true if this is to be set; false to clear the bit
02220  * RETURNS:          <nothing>
02221  *============================================================================*/
02222 void CallStatement::setReturnAfterCall(bool b) {
02223     returnAfterCall = b;
02224 }
02225 
02226 /*==============================================================================
02227  * FUNCTION:         CallStatement::isReturnAfterCall
02228  * OVERVIEW:         Tests a bit that says that this call is effectively followed by a return. This happens e.g. on
02229  *                      Sparc when there is a restore in the delay slot of the call
02230  * PARAMETERS:       none
02231  * RETURNS:          True if this call is effectively followed by a return
02232  *============================================================================*/
02233 bool CallStatement::isReturnAfterCall() {
02234     return returnAfterCall;
02235 }
02236 
02237 /*==============================================================================
02238  * FUNCTION:        CallStatement::clone
02239  * OVERVIEW:        Deep copy clone
02240  * PARAMETERS:      <none>
02241  * RETURNS:         Pointer to a new Statement, a clone of this CallStatement
02242  *============================================================================*/
02243 Statement* CallStatement::clone() {
02244     CallStatement* ret = new CallStatement();
02245     ret->pDest = pDest->clone();
02246     ret->m_isComputed = m_isComputed;
02247     StatementList::iterator ss;
02248     for (ss = arguments.begin(); ss != arguments.end(); ++ss)
02249         ret->arguments.append((*ss)->clone());
02250     for (ss = defines.begin(); ss != defines.end(); ++ss)
02251         ret->defines.append((*ss)->clone());
02252     // Statement members
02253     ret->pbb = pbb;
02254     ret->proc = proc;
02255     ret->number = number;
02256     return ret;
02257 }
02258 
02259 // visit this stmt
02260 bool CallStatement::accept(StmtVisitor* visitor) {
02261     return visitor->visit(this);
02262 }
02263 
02264 Proc* CallStatement::getDestProc() {
02265     return procDest; 
02266 }
02267 
02268 void CallStatement::setDestProc(Proc* dest) { 
02269     assert(dest);
02270     // assert(procDest == NULL);        // No: not convenient for unit testing
02271     procDest = dest;
02272 }
02273 
02274 void CallStatement::generateCode(HLLCode *hll, BasicBlock *pbb, int indLevel) {
02275 
02276     Proc *p = getDestProc();
02277 
02278     if (p == NULL && isComputed()) {
02279         hll->AddIndCallStatement(indLevel, pDest, arguments, calcResults());
02280         return;
02281     }
02282     StatementList* results = calcResults();
02283 
02284 #if 0
02285     LOG << "call: " << this;
02286     LOG << " in proc " << proc->getName() << "\n";
02287 #endif
02288     assert(p);
02289     if (Boomerang::get()->noDecompile) {
02290         if (procDest->getSignature()->getNumReturns() > 0) {
02291             Assign* as = new Assign(new IntegerType(), new Unary(opRegOf, new Const(24)), new Unary(opRegOf, new Const(24)));
02292             as->setProc(proc);
02293             as->setBB(pbb);
02294             results->append(as);
02295         }
02296         
02297         // some hacks
02298         if (std::string(p->getName()) == "printf" ||
02299             std::string(p->getName()) == "scanf") {
02300             for (int i = 1; i < 3; i++) {
02301                 Exp *e = signature->getArgumentExp(i);
02302                 assert(e);
02303                 Location *l = dynamic_cast<Location*>(e);
02304                 if (l) {
02305                     l->setProc(proc);       // Needed?
02306                 }
02307                 Assign* as = new Assign(signature->getParamType(i), e->clone(), e->clone());
02308                 as->setProc(proc);
02309                 as->setBB(pbb);
02310                 as->setNumber(number);      // So fromSSAform will work later
02311                 arguments.append(as);
02312             }
02313         }
02314     }
02315     if (p->isLib() && *p->getSignature()->getPreferedName()) {
02316         hll->AddCallStatement(indLevel, p,  p->getSignature()->getPreferedName(), arguments, results);
02317     } else
02318         hll->AddCallStatement(indLevel, p, p->getName(), arguments, results);
02319 }
02320 
02321 void CallStatement::simplify() {
02322     GotoStatement::simplify();
02323     StatementList::iterator ss;
02324     for (ss = arguments.begin(); ss != arguments.end(); ++ss)
02325         (*ss)->simplify();
02326     for (ss = defines.begin(); ss != defines.end(); ++ss)
02327         (*ss)->simplify();
02328 }
02329 
02330 bool GotoStatement::usesExp(Exp* e) {
02331     Exp* where;
02332     return (pDest->search(e, where));
02333 }
02334 
02335 bool CallStatement::usesExp(Exp *e) {
02336     if (GotoStatement::usesExp(e)) return true;
02337     StatementList::iterator ss;
02338     for (ss = arguments.begin(); ss != arguments.end(); ++ss)
02339         if ((*ss)->usesExp(e)) return true;
02340     for (ss = defines.begin(); ss != defines.end(); ++ss)
02341         if ((*ss)->usesExp(e)) return true;
02342     return false;
02343 }
02344 
02345 void CallStatement::getDefinitions(LocationSet &defs) {
02346     StatementList::iterator dd;
02347     for (dd = defines.begin(); dd != defines.end(); ++dd)
02348         defs.insert(((Assignment*)*dd)->getLeft());
02349     // Childless calls are supposed to define everything. In practice they don't really define things like %pc, so we
02350     // need some extra logic in getTypeFor()
02351     if (isChildless() && !Boomerang::get()->assumeABI)
02352         defs.insert(new Terminal(opDefineAll));
02353 }
02354 
02355 // Attempt to convert this call, if indirect, to a direct call.
02356 // NOTE: at present, we igore the possibility that some other statement will modify the global. This is a serious
02357 // limitation!!
02358 bool CallStatement::convertToDirect() {
02359     if (!m_isComputed)
02360         return false;
02361     bool convertIndirect = false;
02362     Exp *e = pDest;
02363     if (pDest->isSubscript()) {
02364         Statement* def = ((RefExp*)e)->getDef();
02365         if (def && !def->isImplicit())
02366             return false;                       // If an already defined global, don't convert
02367         e = ((RefExp*)e)->getSubExp1();
02368     }
02369     if (e->getOper() == opArrayIndex && 
02370             ((Binary*)e)->getSubExp2()->isIntConst() &&
02371             ((Const*)(((Binary*)e)->getSubExp2()))->getInt() == 0)
02372         e = ((Binary*)e)->getSubExp1();
02373     // Can actually have name{0}[0]{0} !!
02374     if (e->isSubscript())
02375         e = ((RefExp*)e)->getSubExp1();
02376     if (e->isIntConst()) {
02377         // ADDRESS u = (ADDRESS)((Const*)e)->getInt();
02378         // Just convert it to a direct call!
02379         // FIXME: to be completed
02380     } else if (e->isMemOf()) {
02381         // It might be a global that has not been processed yet
02382         Exp* sub = ((Unary*)e)->getSubExp1();
02383         if (sub->isIntConst()) {
02384             // m[K]: convert it to a global right here
02385             ADDRESS u = (ADDRESS)((Const*)sub)->getInt();
02386             proc->getProg()->globalUsed(u);
02387             const char *nam = proc->getProg()->getGlobalName(u);
02388             e = Location::global(nam, proc);
02389             pDest = new RefExp(e, NULL);
02390         }
02391     }
02392     if (!e->isGlobal()) {
02393         return false;
02394     }
02395     char *nam = ((Const*)e->getSubExp1())->getStr();
02396     Prog* prog = proc->getProg();
02397     ADDRESS gloAddr = prog->getGlobalAddr(nam);
02398     ADDRESS dest = prog->readNative4(gloAddr);
02399     // We'd better do some limit checking on the value. This does not guarantee that it's a valid proc pointer, but it
02400     // may help
02401     if (dest < prog->getLimitTextLow() || dest > prog->getLimitTextHigh())
02402         return false;       // Not a valid proc pointer
02403     Proc *p = prog->findProc(nam);
02404     bool bNewProc = p == NULL;
02405     if (bNewProc)
02406         p = prog->setNewProc(dest);
02407     if (VERBOSE)
02408         LOG << (bNewProc ? "new" : "existing") << " procedure for call to global '" << nam << " is " << p->getName() <<
02409             "\n";
02410     // we need to:
02411     // 1) replace the current return set with the return set of the new procDest
02412     // 2) call fixCallBypass (now fixCallAndPhiRefs) on the enclosing procedure
02413     // 3) fix the arguments (this will only affect the implicit arguments, the regular arguments should
02414     //    be empty at this point)
02415     // 3a replace current arguments with those of the new proc
02416     // 3b copy the signature from the new proc
02417     // 4) change this to a non-indirect call
02418     procDest = p;
02419     Signature *sig = p->getSignature();
02420     // pDest is currently still global5{-}, but we may as well make it a constant now, since that's how it will be
02421     // treated now
02422     pDest = new Const(dest);
02423 
02424     // 1
02425     // 2
02426     proc->fixCallAndPhiRefs();
02427 
02428     // 3
02429     // 3a Do the same with the regular arguments
02430     arguments.clear();
02431     for (unsigned i = 0; i < sig->getNumParams(); i++) {
02432         Exp* a = sig->getParamExp(i);
02433         Assign* as = new Assign(new VoidType(), a->clone(), a->clone());
02434         as->setProc(proc);
02435         as->setBB(pbb);
02436         arguments.append(as);
02437     }
02438     // std::cerr << "Step 3a: arguments now: ";
02439     // StatementList::iterator xx; for (xx = arguments.begin(); xx != arguments.end(); ++xx) {
02440     //      ((Assignment*)*xx)->printCompact(std::cerr); std::cerr << ", ";
02441     // } std::cerr << "\n";
02442     // implicitArguments = newimpargs;
02443     // assert((int)implicitArguments.size() == sig->getNumImplicitParams());
02444 
02445     // 3b
02446     signature = p->getSignature()->clone();
02447 
02448     // 4
02449     m_isComputed = false;
02450     proc->undoComputedBB(this);
02451     proc->addCallee(procDest);
02452     procDest->printDetailsXML();
02453     convertIndirect = true;
02454 
02455     if (VERBOSE)
02456         LOG << "Result of convertToDirect: " << this << "\n";
02457     return convertIndirect;
02458 }
02459 
02460 Exp* CallStatement::getArgumentExp(int i)
02461 {
02462     assert(i < (int)arguments.size());
02463     StatementList::iterator aa = arguments.begin();
02464     my_advance(aa, i);
02465     return ((Assign*)*aa)->getRight();
02466 }
02467 
02468 void CallStatement::setArgumentExp(int i, Exp *e)
02469 {
02470     assert(i < (int)arguments.size());
02471     StatementList::iterator aa = arguments.begin();
02472     my_advance(aa, i);
02473     Exp*& a = ((Assign*)*aa)->getRightRef();
02474     a = e->clone();
02475 }
02476 
02477 int CallStatement::getNumArguments()
02478 {
02479     return arguments.size();
02480 }
02481 
02482 void CallStatement::setNumArguments(int n) {
02483     int oldSize = arguments.size();
02484     if (oldSize > n) {
02485         StatementList::iterator aa = arguments.begin();
02486         my_advance(aa, n);
02487         arguments.erase(aa, arguments.end());
02488     }
02489     // MVE: check if these need extra propagation
02490     for (int i = oldSize; i < n; i++) {
02491         Exp* a = procDest->getSignature()->getArgumentExp(i);
02492         Type *ty = procDest->getSignature()->getParamType(i);
02493         if (ty == NULL && oldSize)
02494             ty = procDest->getSignature()->getParamType(oldSize-1);
02495         if (ty == NULL)
02496             ty = new VoidType();
02497         Assign* as = new Assign(ty, a->clone(), a->clone());
02498         as->setProc(proc);
02499         as->setBB(pbb);
02500         arguments.append(as);
02501     }
02502 }
02503 
02504 void CallStatement::removeArgument(int i)
02505 {
02506     StatementList::iterator aa = arguments.begin();
02507     my_advance(aa, i);
02508     arguments.erase(aa);
02509 }
02510 
02511 // Processes each argument of a CallStatement, and the RHS of an Assign. Ad-hoc type analysis only.
02512 Exp *processConstant(Exp *e, Type *t, Prog *prog, UserProc* proc, ADDRESS stmt) {
02513     if (t == NULL) return e;
02514     NamedType *nt = NULL;
02515     if (t->isNamed()) {
02516         nt = (NamedType*)t;
02517         t = ((NamedType*)t)->resolvesTo();
02518     }
02519     if (t == NULL) return e;
02520     // char* and a constant
02521     if (e->isIntConst()) {
02522         if (nt && nt->getName() == "LPCWSTR") {
02523             ADDRESS u = ((Const*)e)->getAddr();
02524             // TODO
02525             LOG << "possible wide char string at " << u << "\n";
02526         }
02527         if (t->resolvesToPointer()) {
02528             PointerType *pt = t->asPointer();
02529             Type *points_to = pt->getPointsTo();
02530             if (t->isCString()) {
02531                 ADDRESS u = ((Const*)e)->getAddr();
02532                 if (u != 0) {   // can't do anything with NULL
02533                     char *str = prog->getStringConstant(u, true);
02534                     if (str) {
02535                         e = new Const(str);
02536                         // Check if we may have guessed this global incorrectly (usually as an array of char)
02537                         const char* nam = prog->getGlobalName(u);
02538                         if (nam) prog->setGlobalType(nam,
02539                             new PointerType(new CharType()));
02540                     } else {
02541                         proc->getProg()->globalUsed(u);
02542                         const char *nam = proc->getProg()->getGlobalName(u);
02543                         if (nam)
02544                             e = Location::global(nam, proc);
02545                     }
02546                 }
02547             }
02548             if (points_to->resolvesToFunc()) {
02549                 ADDRESS a = ((Const*)e)->getAddr();
02550                 if (VERBOSE || 1)
02551                     LOG << "found function pointer with constant value " << "of type " << pt->getCtype() 
02552                         << " in statement at addr " << stmt << ".  Decoding address " << a << "\n";
02553                 // the address can be zero, i.e., NULL, if so, ignore it.
02554                 if (a != 0) {
02555                     if (!Boomerang::get()->noDecodeChildren)
02556                         prog->decodeEntryPoint(a);
02557                     Proc *p = prog->findProc(a);
02558                     if (p) {
02559                         Signature *sig = points_to->asFunc()->getSignature()->clone();
02560                         if (sig->getName() == NULL ||
02561                             strlen(sig->getName()) == 0 || 
02562                             !strcmp(sig->getName(), "<ANON>") ||
02563                             prog->findProc(sig->getName()) != NULL)
02564                             sig->setName(p->getName());
02565                         else
02566                             p->setName(sig->getName());
02567                         sig->setForced(true);
02568                         p->setSignature(sig);
02569                         e = Location::global(p->getName(), proc);
02570                     }
02571                 }
02572             }
02573         } else if (t->resolvesToFloat()) {
02574             e = new Ternary(opItof, new Const(32), new Const(t->getSize()), e);
02575         } 
02576     }
02577 
02578     return e;
02579 }
02580 
02581 Type* Assignment::getTypeFor(Exp* e) {
02582     // assert(*lhs == *e);          // No: local vs base expression
02583     return type;
02584 }
02585 
02586 void Assignment::setTypeFor(Exp* e, Type* ty) {
02587     // assert(*lhs == *e);
02588     Type* oldType = type;
02589     type = ty;
02590     if (DEBUG_TA && oldType != ty)
02591         LOG << "    changed type of " << this << "  (type was " << oldType->getCtype() << ")\n";
02592 }
02593 
02594 // Scan the returns for e. If found, return the type associated with that return
02595 Type* CallStatement::getTypeFor(Exp* e) {
02596     // The defines "cache" what the destination proc is defining
02597     Assignment* as = defines.findOnLeft(e);
02598     if (as != NULL)
02599         return as->getType();
02600     if (e->isPC())
02601         // Special case: just return void*
02602         return new PointerType(new VoidType);
02603     return new VoidType;
02604 }
02605 
02606 void CallStatement::setTypeFor(Exp* e, Type* ty) {
02607     Assignment* as = defines.findOnLeft(e);
02608     if (as != NULL)
02609         return as->setType(ty);
02610     // See if it is in our reaching definitions
02611     Exp* ref = defCol.findDefFor(e);
02612     if (ref == NULL || !ref->isSubscript()) return;
02613     Statement* def = ((RefExp*)ref)->getDef();
02614     if (def == NULL) return;
02615     def->setTypeFor(e, ty);
02616 }
02617 
02618 
02619 // This function has two jobs. One is to truncate the list of arguments based on the format string.
02620 // The second is to add parameter types to the signature.
02621 // If -Td is used, type analysis will be rerun with these changes.
02622 bool CallStatement::ellipsisProcessing(Prog* prog) {
02623 
02624     // if (getDestProc() == NULL || !getDestProc()->getSignature()->hasEllipsis())
02625     if (getDestProc() == NULL || !signature->hasEllipsis())
02626         return false;
02627     // functions like printf almost always have too many args
02628     std::string name(getDestProc()->getName());
02629     int format = -1;
02630     if ((name == "printf" || name == "scanf")) 
02631         format = 0;
02632     else if (name == "sprintf" || name == "fprintf" || name == "sscanf") 
02633         format = 1;
02634     else if (getNumArguments() && getArgumentExp(getNumArguments()-1)->isStrConst())
02635         format = getNumArguments() - 1;
02636     else return false;
02637     if (VERBOSE)
02638         LOG << "ellipsis processing for " << name << "\n";
02639     char* formatStr = NULL;
02640     Exp* formatExp = getArgumentExp(format);
02641     // We sometimes see a[m[blah{...}]]
02642     if (formatExp->isAddrOf()) {
02643         formatExp = ((Unary*)formatExp)->getSubExp1();
02644         if (formatExp->isSubscript())
02645             formatExp = ((RefExp*)formatExp)->getSubExp1();
02646         if (formatExp->isMemOf())
02647             formatExp = ((Unary*)formatExp)->getSubExp1();
02648     }
02649     if (formatExp->isSubscript()) {
02650         // Maybe it's defined to be a Const string
02651         Statement* def = ((RefExp*)formatExp)->getDef();
02652         if (def == NULL) return false;      // Not all NULL refs get converted to implicits
02653         if (def->isAssign()) {
02654             // This would be unusual; propagation would normally take care of this
02655             Exp* rhs = ((Assign*)def)->getRight();
02656             if (rhs == NULL || !rhs->isStrConst()) return false;
02657             formatStr = ((Const*)rhs)->getStr();
02658         } else if (def->isPhi()) {
02659             // More likely. Example: switch_gcc. Only need ONE candidate format string
02660             PhiAssign* pa = (PhiAssign*)def;
02661             int n = pa->getNumDefs();
02662             for (int i=0; i < n; i++) {
02663                 def = pa->getStmtAt(i);
02664                 if (def == NULL) continue;
02665                 if (!def->isAssign()) continue;
02666                 Exp* rhs = ((Assign*)def)->getRight();
02667                 if (rhs == NULL || !rhs->isStrConst()) continue;
02668                 formatStr = ((Const*)rhs)->getStr();
02669                 break;
02670             }
02671             if (formatStr == NULL) return false;
02672         } else return false;
02673     } else if (formatExp->isStrConst()) {
02674         formatStr = ((Const*)formatExp)->getStr();
02675     } else return false;
02676     // actually have to parse it
02677     // Format string is: % [flags] [width] [.precision] [size] type
02678     int n = 1;      // Count the format string itself (may also be "format" more arguments)
02679     char ch;
02680     // Set a flag if the name of the function is scanf/sscanf/fscanf
02681     bool isScanf = name == "scanf" || name.substr(1, 5) == "scanf";
02682     char *p = formatStr;
02683     while ((p = strchr(p, '%'))) {
02684         p++;                // Point past the %
02685         bool veryLong = false;          // %lld or %L
02686         do {
02687             ch = *p++;      // Skip size and precisionA
02688             switch (ch) {
02689                 case '*':
02690                     // Example: printf("Val: %*.*f\n", width, precision, val);
02691                     n++;        // There is an extra parameter for the width or precision
02692                     // This extra parameter is of type integer, never int* (so pass false as last argument)
02693                     addSigParam(new IntegerType(), false);
02694                     continue;
02695                 case '-': case '+': case '#': case ' ':
02696                     // Flag. Ignore
02697                     continue;
02698                 case '.':
02699                     // Separates width and precision. Ignore.
02700                     continue;
02701                 case 'h': case 'l':
02702                     // size of half or long. Argument is usually still one word. Ignore.
02703                     // Exception: %llx
02704                     // TODO: handle architectures where l implies two words
02705                     // TODO: at least h has implications for scanf
02706                     if (*p == 'l') {
02707                         // %llx
02708                         p++;        // Skip second l
02709                         veryLong = true;
02710                     }
02711                     continue;
02712                 case 'L':
02713                     // long. TODO: handle L for long doubles.
02714                     // n++;     // At least chew up one more parameter so later types are correct
02715                     veryLong = true;
02716                     continue;
02717                 default:
02718                     if ('0' <= ch && ch <= '9') continue;   // width or precision
02719                     break;                                  // Else must be format type, handled below
02720             }
02721             break;
02722         } while (1);
02723         if (ch != '%')      // Don't count %%
02724             n++;
02725         switch (ch) {
02726             case 'd': case 'i':                         // Signed integer
02727                 addSigParam(new IntegerType(veryLong ? 64 : 32), isScanf);
02728                 break;
02729             case 'u': case 'x': case 'X': case 'o':     // Unsigned integer
02730                 addSigParam(new IntegerType(32, -1), isScanf);
02731                 break;
02732             case 'f': case 'g': case 'G': case 'e': case 'E':   // Various floating point formats
02733                 // Note that for scanf, %f means float, and %lf means double, whereas for printf, both of these mean
02734                 // double
02735                 addSigParam(new FloatType(veryLong ? 128 : (isScanf ? 32 : 64)), isScanf);// Note: may not be 64 bits
02736                                                                                         // for some archs
02737                 break;
02738             case 's':                                   // String
02739                 addSigParam(new PointerType(new ArrayType(new CharType)), isScanf);
02740                 break;
02741             case 'c':                                   // Char
02742                 addSigParam(new CharType, isScanf);
02743                 break;
02744             case '%':
02745                 break;          // Ignore %% (emits 1 percent char)
02746             default:
02747                 LOG << "Unhandled format character " << ch << " in format string for call " << this << "\n";
02748         }
02749     }
02750     setNumArguments(format + n);
02751     signature->killEllipsis();  // So we don't do this again
02752     return true;
02753 }
02754 
02755 // Make an assign suitable for use as an argument from a callee context expression
02756 Assign* CallStatement::makeArgAssign(Type* ty, Exp* e) {
02757     Exp* lhs = e->clone();
02758     localiseComp(lhs);          // Localise the components of lhs (if needed)
02759     Exp* rhs = localiseExp(e->clone());
02760     Assign* as = new Assign(ty, lhs, rhs);
02761     as->setProc(proc);
02762     as->setBB(pbb);
02763     // It may need implicit converting (e.g. sp{-} -> sp{0})
02764     Cfg* cfg = proc->getCFG();
02765     if (cfg->implicitsDone()) {
02766         ImplicitConverter ic(cfg);
02767         StmtImplicitConverter sm(&ic, cfg);
02768         as->accept(&sm);
02769     }
02770     return as;
02771 }
02772 
02773 // Helper function for the above
02774 void CallStatement::addSigParam(Type* ty, bool isScanf) {
02775     if (isScanf) ty = new PointerType(ty);
02776     signature->addParameter(ty);
02777     Exp* paramExp = signature->getParamExp(signature->getNumParams()-1);
02778     if (VERBOSE)
02779         LOG << "  ellipsisProcessing: adding parameter " << paramExp << " of type " << ty->getCtype() << "\n";
02780     if (arguments.size() < (unsigned)signature->getNumParams()) {
02781         Assign* as = makeArgAssign(ty, paramExp);
02782         arguments.append(as);
02783     }
02784 }
02785 
02786 /**********************************
02787  * ReturnStatement methods
02788  **********************************/
02789 
02790 /*==============================================================================
02791  * FUNCTION:         ReturnStatement::ReturnStatement
02792  * OVERVIEW:         Constructor.
02793  * PARAMETERS:       None
02794  * RETURNS:          <nothing>
02795  *============================================================================*/
02796 ReturnStatement::ReturnStatement() : retAddr(NO_ADDRESS) {
02797     kind = STMT_RET;
02798 }
02799 
02800 /*==============================================================================
02801  * FUNCTION:         ReturnStatement::~ReturnStatement
02802  * OVERVIEW:         Destructor.
02803  * PARAMETERS:       <none>
02804  * RETURNS:          <nothing>
02805  *============================================================================*/
02806 ReturnStatement::~ReturnStatement() {
02807 }
02808 
02809 /*==============================================================================
02810  * FUNCTION:        ReturnStatement::clone
02811  * OVERVIEW:        Deep copy clone
02812  * PARAMETERS:      <none>
02813  * RETURNS:         Pointer to a new Statement, a clone of this ReturnStatement
02814  *============================================================================*/
02815 Statement* ReturnStatement::clone() {
02816     ReturnStatement* ret = new ReturnStatement();
02817     iterator rr;
02818     for (rr = modifieds.begin(); rr != modifieds.end(); ++rr)
02819         ret->modifieds.append((ImplicitAssign*)(*rr)->clone());
02820     for (rr = returns.begin(); rr != returns.end(); ++rr)
02821         ret->returns.append((Assignment*)(*rr)->clone());
02822     ret->retAddr = retAddr;
02823     ret->col.makeCloneOf(col);
02824     // Statement members
02825     ret->pbb = pbb;
02826     ret->proc = proc;
02827     ret->number = number;
02828     return ret;
02829 }
02830 
02831 // visit this stmt
02832 bool ReturnStatement::accept(StmtVisitor* visitor) {
02833     return visitor->visit(this);
02834 }
02835 
02836 void ReturnStatement::generateCode(HLLCode *hll, BasicBlock *pbb, int indLevel) {
02837     hll->AddReturnStatement(indLevel, &getReturns());
02838 }
02839 
02840 void ReturnStatement::simplify() {
02841     iterator it;
02842     for (it = modifieds.begin(); it != modifieds.end(); it++)
02843         (*it)->simplify();
02844     for (it = returns.begin(); it != returns.end(); it++)
02845         (*it)->simplify();
02846 }
02847 
02848 // Remove the return (if any) related to loc. Loc may or may not be subscripted
02849 void ReturnStatement::removeReturn(Exp* loc) {
02850     if (loc->isSubscript())
02851         loc = ((Location*)loc)->getSubExp1();
02852     iterator rr;
02853     for (rr = returns.begin(); rr != returns.end(); ++rr) {
02854         if (*((Assignment*)*rr)->getLeft() == *loc) {
02855             returns.erase(rr);
02856             return;                 // Assume only one definition
02857         }
02858     }
02859 }
02860 
02861 void ReturnStatement::addReturn(Assignment* a) {
02862     returns.append(a);
02863 }
02864 
02865 
02866 bool ReturnStatement::search(Exp* search, Exp*& result) {
02867     result = NULL;
02868     ReturnStatement::iterator rr;
02869     for (rr = begin(); rr != end(); ++rr) {
02870         if ((*rr)->search(search, result))
02871             return true;
02872     }
02873     return false;
02874 }
02875 
02876 bool ReturnStatement::searchAndReplace(Exp* search, Exp* replace, bool cc) {
02877     bool change = false;
02878     ReturnStatement::iterator rr;
02879     for (rr = begin(); rr != end(); ++rr)
02880         change |= (*rr)->searchAndReplace(search, replace, cc);
02881     if (cc) {
02882         DefCollector::iterator dd;
02883         for (dd = col.begin(); dd != col.end(); ++dd)
02884             change |= (*dd)->searchAndReplace(search, replace);
02885     }
02886     return change;
02887 }
02888 
02889 bool ReturnStatement::searchAll(Exp* search, std::list<Exp *>& result) {
02890     bool found = false;
02891     ReturnStatement::iterator rr;
02892     for (rr = begin(); rr != end(); ++rr) {
02893         if ((*rr)->searchAll(search, result))
02894             found = true;
02895     }
02896     return found;
02897 }
02898 
02899 bool CallStatement::isDefinition() {
02900     LocationSet defs;
02901     getDefinitions(defs);
02902     return defs.size() != 0;
02903 }
02904 
02905 bool ReturnStatement::usesExp(Exp *e) {
02906     Exp *where;
02907     ReturnStatement::iterator rr;
02908     for (rr = begin(); rr != end(); ++rr) {
02909         if ((*rr)->search(e, where))
02910             return true;
02911     }
02912     return false;
02913 }
02914 
02915 /**********************************************************************
02916  * BoolAssign methods
02917  * These are for statements that set a destination (usually to 1 or 0)
02918  * depending in a condition code (e.g. Pentium)
02919  **********************************************************************/
02920 
02921 /*==============================================================================
02922  * FUNCTION:         BoolAssign::BoolAssign
02923  * OVERVIEW:         Constructor.
02924  * PARAMETERS:       sz: size of the assignment
02925  * RETURNS:          <N/a>
02926  *============================================================================*/
02927 BoolAssign::BoolAssign(int sz): Assignment(NULL), jtCond((BRANCH_TYPE)0),
02928   pCond(NULL), bFloat(false), size(sz) {
02929     kind = STMT_BOOLASSIGN;
02930 }
02931 
02932 /*==============================================================================
02933  * FUNCTION:        BoolAssign::~BoolAssign
02934  * OVERVIEW:        Destructor
02935  * PARAMETERS:      None
02936  * RETURNS:         N/a
02937  *============================================================================*/
02938 BoolAssign::~BoolAssign() {
02939     if (pCond)
02940         ;//delete pCond;
02941 }
02942 
02943 /*==============================================================================
02944  * FUNCTION:        BoolAssign::setCondType
02945  * OVERVIEW:        Sets the BRANCH_TYPE of this jcond as well as the flag
02946  *                  indicating whether or not the floating point condition codes
02947  *                  are used.
02948  * PARAMETERS:      cond - the BRANCH_TYPE
02949  *                  usesFloat - this condional jump checks the floating point
02950  *                    condition codes
02951  * RETURNS:         a semantic string
02952  *============================================================================*/
02953 void BoolAssign::setCondType(BRANCH_TYPE cond, bool usesFloat /*= false*/) {
02954     jtCond = cond;
02955     bFloat = usesFloat;
02956     setCondExpr(new Terminal(opFlags));
02957 }
02958 
02959 /*==============================================================================
02960  * FUNCTION:        BoolAssign::makeSigned
02961  * OVERVIEW:        Change this from an unsigned to a signed branch
02962  * NOTE:            Not sure if this is ever going to be used
02963  * PARAMETERS:      <none>
02964  * RETURNS:         <nothing>
02965  *============================================================================*/
02966 void BoolAssign::makeSigned() {
02967     // Make this into a signed branch
02968     switch (jtCond)
02969     {
02970         case BRANCH_JUL : jtCond = BRANCH_JSL;  break;
02971         case BRANCH_JULE: jtCond = BRANCH_JSLE; break;
02972         case BRANCH_JUGE: jtCond = BRANCH_JSGE; break;
02973         case BRANCH_JUG : jtCond = BRANCH_JSG;  break;
02974         default:
02975             // Do nothing for other cases
02976             break;
02977     }
02978 }
02979 
02980 /*==============================================================================
02981  * FUNCTION:        BoolAssign::getCondExpr
02982  * OVERVIEW:        Return the Exp expression containing the HL condition.
02983  * PARAMETERS:      <none>
02984  * RETURNS:         a semantic string
02985  *============================================================================*/
02986 Exp* BoolAssign::getCondExpr() {
02987     return pCond;
02988 }
02989 
02990 /*==============================================================================
02991  * FUNCTION:        BoolAssign::setCondExpr
02992  * OVERVIEW:        Set the Exp expression containing the HL condition.
02993  * PARAMETERS:      Pointer to semantic string to set
02994  * RETURNS:         <nothing>
02995  *============================================================================*/
02996 void BoolAssign::setCondExpr(Exp* pss) {
02997     if (pCond) ;//delete pCond;
02998     pCond = pss;
02999 }
03000 
03001 /*==============================================================================
03002  * FUNCTION:        BoolAssign::print
03003  * OVERVIEW:        Write a text representation to the given stream
03004  * PARAMETERS:      os: stream
03005  * RETURNS:         <Nothing>
03006  *============================================================================*/
03007 void BoolAssign::printCompact(std::ostream& os /*= cout*/, bool html) {
03008     os << "BOOL ";
03009     lhs->print(os);
03010     os << " := CC(";
03011     switch (jtCond) {
03012         case BRANCH_JE:    os << "equals"; break;
03013         case BRANCH_JNE:   os << "not equals"; break;
03014         case BRANCH_JSL:   os << "signed less"; break;
03015         case BRANCH_JSLE:  os << "signed less or equals"; break;
03016         case BRANCH_JSGE:  os << "signed greater or equals"; break;
03017         case BRANCH_JSG:   os << "signed greater"; break;
03018         case BRANCH_JUL:   os << "unsigned less"; break;
03019         case BRANCH_JULE:  os << "unsigned less or equals"; break;
03020         case BRANCH_JUGE:  os << "unsigned greater or equals"; break;
03021         case BRANCH_JUG:   os << "unsigned greater"; break;
03022         case BRANCH_JMI:   os << "minus"; break;
03023         case BRANCH_JPOS:  os << "plus"; break;
03024         case BRANCH_JOF:   os << "overflow"; break;
03025         case BRANCH_JNOF:  os << "no overflow"; break;
03026         case BRANCH_JPAR:  os << "ev parity"; break;
03027     }
03028     os << ")";
03029     if (bFloat) os << ", float";
03030     if (html)
03031         os << "<br>";
03032     os << std::endl;
03033     if (pCond) {
03034         os << "High level: ";
03035         pCond->print(os, html);
03036         if (html)
03037             os << "<br>";
03038         os << "\n";
03039     }
03040 }
03041 
03042 /*==============================================================================
03043  * FUNCTION:        BoolAssign::clone
03044  * OVERVIEW:        Deep copy clone
03045  * PARAMETERS:      <none>
03046  * RETURNS:         Pointer to a new Statement, a clone of this BoolAssign
03047  *============================================================================*/
03048 Statement* BoolAssign::clone() {
03049     BoolAssign* ret = new BoolAssign(size);
03050     ret->jtCond = jtCond;
03051     if (pCond) ret->pCond = pCond->clone();
03052     else ret->pCond = NULL;
03053     ret->bFloat = bFloat;
03054     ret->size = size;
03055     // Statement members
03056     ret->pbb = pbb;
03057     ret->proc = proc;
03058     ret->number = number;
03059     return ret;
03060 }
03061 
03062 // visit this Statement
03063 bool BoolAssign::accept(StmtVisitor* visitor) {
03064     return visitor->visit(this);
03065 }
03066 
03067 void BoolAssign::generateCode(HLLCode *hll, BasicBlock *pbb, int indLevel) {
03068     assert(lhs);
03069     assert(pCond);
03070     // lhs := (pCond) ? 1 : 0
03071     Assign as(lhs->clone(), new Ternary(opTern, pCond->clone(),
03072       new Const(1), new Const(0)));
03073     hll->AddAssignmentStatement(indLevel, &as);
03074 }
03075 
03076 void BoolAssign::simplify() {
03077     if (pCond)
03078         condToRelational(pCond, jtCond);
03079 }
03080 
03081 void BoolAssign::getDefinitions(LocationSet &defs) 
03082 {
03083     defs.insert(getLeft());
03084 }
03085 
03086 bool BoolAssign::usesExp(Exp *e)
03087 {
03088     assert(lhs && pCond);
03089     Exp *where = 0;
03090     return (pCond->search(e, where) || (lhs->isMemOf() && 
03091         ((Unary*)lhs)->getSubExp1()->search(e, where)));
03092 }
03093 
03094 bool BoolAssign::search(Exp *search, Exp *&result)
03095 {
03096     assert(lhs);
03097     if (lhs->search(search, result)) return true;
03098     assert(pCond);
03099     return pCond->search(search, result);
03100 }
03101 
03102 bool BoolAssign::searchAll(Exp* search, std::list<Exp*>& result)
03103 {
03104     bool ch = false;
03105     assert(lhs);
03106     if (lhs->searchAll(search, result)) ch = true;
03107     assert(pCond);
03108     return pCond->searchAll(search, result) || ch;
03109 }
03110 
03111 bool BoolAssign::searchAndReplace(Exp *search, Exp *replace, bool cc) {
03112     bool chl, chr;
03113     assert(pCond);
03114     assert(lhs);
03115     pCond = pCond->searchReplaceAll(search, replace, chl);
03116      lhs  =   lhs->searchReplaceAll(search, replace, chr);
03117     return chl | chr;
03118 }
03119 
03120 // This is for setting up SETcc instructions; see include/decoder.h macro SETS
03121 void BoolAssign::setLeftFromList(std::list<Statement*>* stmts) {
03122     assert(stmts->size() == 1);
03123     Assign* first = (Assign*)stmts->front();
03124     assert(first->getKind() == STMT_ASSIGN);
03125     lhs = first->getLeft();
03126 }
03127 
03128 //  //  //  //
03129 // Assign //
03130 //  //  //  //
03131 
03132 Assignment::Assignment(Exp* lhs) : TypingStatement(new VoidType), lhs(lhs) {
03133     if (lhs && lhs->isRegOf()) {
03134         int n = ((Const*)lhs->getSubExp1())->getInt();
03135         if (((Location*)lhs)->getProc()) {
03136             type = new SizeType(((Location*)lhs)->getProc()->getProg()->getRegSize(n));
03137         }
03138     }
03139 
03140 }
03141 Assignment::Assignment(Type* ty, Exp* lhs) : TypingStatement(ty), lhs(lhs) {}
03142 Assignment::~Assignment() {}
03143 
03144 Assign::Assign(Exp* lhs, Exp* rhs, Exp* guard)
03145   : Assignment(lhs), rhs(rhs), guard(guard) {
03146     kind = STMT_ASSIGN;
03147 }
03148 
03149 Assign::Assign(Type* ty, Exp* lhs, Exp* rhs, Exp* guard)
03150   : Assignment(ty, lhs), rhs(rhs), guard(guard) 
03151 {
03152     kind = STMT_ASSIGN;
03153 }
03154 Assign::Assign(Assign& o) : Assignment(lhs->clone()) {
03155     kind = STMT_ASSIGN;
03156     rhs = o.rhs->clone();
03157     if (o.type)  type  = o.type->clone();  else type  = NULL;
03158     if (o.guard) guard = o.guard->clone(); else guard = NULL;
03159 }
03160 
03161 // Implicit Assignment
03162 // Constructor and subexpression
03163 ImplicitAssign::ImplicitAssign(Exp* lhs) : Assignment(lhs) {
03164     kind = STMT_IMPASSIGN;
03165 }
03166 // Constructor, type, and subexpression
03167 ImplicitAssign::ImplicitAssign(Type* ty, Exp* lhs) : Assignment(ty, lhs) {
03168     kind = STMT_IMPASSIGN;
03169 }
03170 ImplicitAssign::ImplicitAssign(ImplicitAssign& o) : Assignment(type?type->clone():NULL, lhs->clone()) {
03171     kind = STMT_IMPASSIGN;
03172 }
03173 // The first virtual function (here the destructor) can't be in statement.h file for gcc
03174 ImplicitAssign::~ImplicitAssign() { }
03175 
03176 Statement* Assign::clone() {
03177     Assign* a = new Assign(type == NULL ? NULL : type->clone(), lhs->clone(), rhs->clone(),
03178         guard == NULL ? NULL : guard->clone());
03179     // Statement members
03180     a->pbb = pbb;
03181     a->proc = proc;
03182     a->number = number;
03183     return a;
03184 }
03185 
03186 Statement* PhiAssign::clone() {
03187     PhiAssign* pa = new PhiAssign(type, lhs);
03188     Definitions::iterator dd;
03189     for (dd = defVec.begin(); dd != defVec.end(); dd++) {
03190         PhiInfo pi;
03191         pi.def = dd->def;           // Don't clone the Statement pointer (never moves)
03192         pi.e = dd->e->clone();      // Do clone the expression pointer
03193         pa->defVec.push_back(pi);
03194     }
03195     return pa;
03196 }
03197 
03198 Statement* ImplicitAssign::clone() {
03199     ImplicitAssign* ia = new ImplicitAssign(type, lhs);
03200     return ia;
03201 }
03202 
03203 // visit this Statement
03204 bool Assign::accept(StmtVisitor* visitor) {
03205     return visitor->visit(this);
03206 }
03207 bool PhiAssign::accept(StmtVisitor* visitor) {
03208     return visitor->visit(this);
03209 }
03210 bool ImplicitAssign::accept(StmtVisitor* visitor) {
03211     return visitor->visit(this);
03212 }
03213 
03214 void Assign::simplify() {
03215     // simplify arithmetic of assignment
03216     OPER leftop = lhs->getOper();
03217     if (Boomerang::get()->noBranchSimplify) {
03218         if (leftop == opZF || leftop == opCF || leftop == opOF || leftop == opNF)
03219             return;
03220     }
03221 
03222     lhs = lhs->simplifyArith();
03223     rhs = rhs->simplifyArith();
03224     if (guard) guard = guard->simplifyArith();
03225     // simplify the resultant expression
03226     lhs = lhs->simplify();
03227     rhs = rhs->simplify();
03228     if (guard) guard = guard->simplify();
03229 
03230     // Perhaps the guard can go away
03231     if (guard && (guard->isTrue() || guard->isIntConst() && ((Const*)guard)->getInt() == 1))
03232         guard = NULL;           // No longer a guarded assignment
03233 
03234     if (lhs->getOper() == opMemOf) {
03235         lhs->setSubExp1(lhs->getSubExp1()->simplifyArith());
03236     }
03237 
03238     // this hack finds address constants.. it should go away when Mike writes some decent type analysis.
03239 #if 0
03240     if (DFA_TYPE_ANALYSIS) return;
03241     if (lhs->getOper() == opMemOf && lhs->getSubExp1()->getOper() == opSubscript) {
03242         RefExp *ref = (RefExp*)lhs->getSubExp1();
03243         Statement *phist = ref->getDef();
03244         PhiAssign *phi = NULL;
03245         if (phist /* && phist->getRight() */)       // ?
03246             phi = dynamic_cast<PhiAssign*>(phist);
03247         for (int i = 0; phi && i < phi->getNumDefs(); i++) {
03248             if (phi->getStmtAt(i)) {
03249                 Assign *def = dynamic_cast<Assign*>(phi->getStmtAt(i));
03250                 // Look for rX{-} - K or K
03251                 if (def && (def->rhs->isIntConst() ||
03252                         (def->rhs->getOper() == opMinus &&
03253                         def->rhs->getSubExp1()->isSubscript() &&
03254                         ((RefExp*)def->rhs->getSubExp1())->isImplicitDef() &&
03255                         def->rhs->getSubExp1()->getSubExp1()->isRegOf() &&
03256                         def->rhs->getSubExp2()->isIntConst()))) {
03257                     Exp *ne = new Unary(opAddrOf, Location::memOf(def->rhs, proc)); 
03258                     if (VERBOSE)
03259                         LOG << "replacing " << def->rhs << " with " << ne << " in " << def << "\n";
03260                     def->rhs = ne;
03261                 }
03262                 if (def && def->rhs->getOper() == opAddrOf &&
03263                         def->rhs->getSubExp1()->getOper() == opSubscript &&
03264                         def->rhs->getSubExp1()->getSubExp1()->getOper() == opGlobal &&
03265                         // MVE: opPhi!!
03266                         rhs->getOper() != opPhi && rhs->getOper() != opItof &&
03267                         rhs->getOper() != opFltConst) {
03268                     Type *ty = proc->getProg()->getGlobalType(
03269                                  ((Const*)def->rhs->getSubExp1()->
03270                                                     getSubExp1()->
03271                                                     getSubExp1())->getStr());
03272                     if (ty && ty->isArray()) {
03273                         Type *bty = ((ArrayType*)ty)->getBaseType();
03274                         if (bty->isFloat()) {
03275                             if (VERBOSE)
03276                                 LOG << "replacing " << rhs << " with ";
03277                             rhs = new Ternary(opItof, new Const(32), new Const(bty->getSize()), rhs);
03278                             if (VERBOSE)
03279                                 LOG << rhs << " (assign indicates float type)\n";
03280                         }
03281                     }
03282                 }
03283             }
03284         }
03285     }
03286 #endif
03287 }
03288 
03289 void Assign::simplifyAddr() {
03290     lhs = lhs->simplifyAddr();
03291     rhs = rhs->simplifyAddr();
03292 }
03293 
03294 void Assignment::simplifyAddr() {
03295     lhs = lhs->simplifyAddr();
03296 }
03297 
03298 
03299 void Assign::fixSuccessor() {
03300     lhs = lhs->fixSuccessor();
03301     rhs = rhs->fixSuccessor();
03302 }
03303 
03304 void Assignment::print(std::ostream& os, bool html) {
03305     os << std::setw(4) << std::dec << number << " ";
03306     if (html) {
03307         os << "</td><td>";
03308         os << "<a name=\"stmt" << std::dec << number << "\">";
03309     }
03310     printCompact(os, html);
03311     if (html)
03312         os << "</a>";
03313     if (!ranges.empty()) {
03314         os << "\n\t\t\tranges: ";
03315         ranges.print(os);
03316     }
03317 }
03318 void Assign::printCompact(std::ostream& os, bool html) {
03319     os << "*" << type << "* ";
03320     if (guard) 
03321         os << guard << " => ";
03322     if (lhs) lhs->print(os, html);
03323     os << " := ";
03324     if (rhs) rhs->print(os, html);
03325 }
03326 void PhiAssign::printCompact(std::ostream& os, bool html) {
03327     os << "*" << type << "* ";
03328     if (lhs) lhs->print(os, html);
03329     os << " := phi";
03330     // Print as lhs := phi{9 17} for the common case where the lhs is the same location as all the referenced
03331     // locations. When not, print as local4 := phi(r24{9} argc{17})
03332     bool simple = true;
03333     int i, n = defVec.size();
03334     if (n != 0) {
03335         for (i = 0; i < n; i++) {
03336             // If e is NULL assume it is meant to match lhs
03337             if (defVec[i].e == NULL) continue;
03338             if (! (*defVec[i].e == *lhs)) {
03339                 // One of the phi parameters has a different base expression to lhs. Use non simple print.
03340                 simple = false;
03341                 break;
03342             }
03343         }
03344     }
03345     iterator it;
03346     if (simple) {
03347         os << "{" << std::dec;
03348         for (it = defVec.begin(); it != defVec.end(); /* no increment */) {
03349             if (it->def) {
03350                 if (html)
03351                     os << "<a href=\"#stmt" << std::dec << it->def->getNumber() << "\">";
03352                 os << it->def->getNumber();
03353                 if (html)
03354                     os << "</a>";
03355             } else
03356                 os << "-";
03357             if (++it != defVec.end())
03358                 os << " ";
03359         }
03360         os << "}";
03361     } else {
03362         os << "(";
03363         for (it = defVec.begin(); it != defVec.end(); /* no increment */) {
03364             Exp* e = it->e;
03365             if (e == NULL)
03366                 os << "NULL{";
03367             else
03368                 os << e << "{";
03369             if (it->def)
03370                 os << std::dec << it->def->getNumber();
03371             else
03372                 os << "-";
03373             os << "}";
03374             if (++it != defVec.end())
03375                 os << " ";
03376         }
03377         os << ")";
03378     }
03379 }
03380 void ImplicitAssign::printCompact(std::ostream& os, bool html) {
03381     os << "*" << type << "* ";
03382     if (lhs) lhs->print(os, html);
03383     os << " := -";
03384 }
03385 
03386 
03387 
03388 // All the Assignment-derived classes have the same definitions: the lhs
03389 void Assignment::getDefinitions(LocationSet &defs) {
03390     if (lhs->getOper() == opAt)                         // foo@[m:n] really only defines foo
03391         defs.insert(((Ternary*)lhs)->getSubExp1());
03392     else
03393         defs.insert(lhs);
03394     // Special case: flag calls define %CF (and others)
03395     if (lhs->isFlags()) {
03396         defs.insert(new Terminal(opCF));
03397         defs.insert(new Terminal(opZF));
03398     }
03399 }
03400 
03401 bool Assign::search(Exp* search, Exp*& result) {
03402     if (lhs->search(search, result))
03403         return true;
03404     return rhs->search(search, result);
03405 }
03406 bool PhiAssign::search(Exp* search, Exp*& result) {
03407     if (lhs->search(search, result))
03408         return true;
03409     iterator it;
03410     for (it = defVec.begin(); it != defVec.end(); ++it) {
03411         if (it->e == NULL) continue;            // Note: can't match foo{-} because of this
03412         RefExp* re = new RefExp(it->e, it->def);
03413         if (re->search(search, result))
03414             return true;
03415     }
03416     return false;
03417 }
03418 bool ImplicitAssign::search(Exp* search, Exp*& result) {
03419     return lhs->search(search, result);
03420 }
03421 
03422 bool Assign::searchAll(Exp* search, std::list<Exp*>& result) {
03423     bool res;
03424     std::list<Exp*> leftResult;
03425     std::list<Exp*>::iterator it;
03426     res = lhs->searchAll(search, leftResult);
03427     // Ugh: searchAll clears the list!
03428     res |= rhs->searchAll(search, result);
03429     for (it = leftResult.begin(); it != leftResult.end(); it++)
03430         result.push_back(*it);
03431     return res;
03432 }
03433 // FIXME: is this the right semantics for searching a phi statement, disregarding the RHS?
03434 bool PhiAssign::searchAll(Exp* search, std::list<Exp*>& result) {
03435     return lhs->searchAll(search, result);
03436 }
03437 bool ImplicitAssign::searchAll(Exp* search, std::list<Exp*>& result) {
03438     return lhs->searchAll(search, result);
03439 }
03440 
03441 bool Assign::searchAndReplace(Exp* search, Exp* replace, bool cc) {
03442     bool chl, chr, chg = false;
03443     lhs = lhs->searchReplaceAll(search, replace, chl);
03444     rhs = rhs->searchReplaceAll(search, replace, chr);
03445     if (guard)
03446         guard = guard->searchReplaceAll(search, replace, chg);
03447     return chl | chr | chg;
03448 }
03449 bool PhiAssign::searchAndReplace(Exp* search, Exp* replace, bool cc) {
03450     bool change;
03451     lhs = lhs->searchReplaceAll(search, replace, change);
03452     std::vector<PhiInfo>::iterator it;
03453     for (it = defVec.begin(); it != defVec.end(); it++) {
03454         if (it->e == NULL) continue;
03455         bool ch;
03456         // Assume that the definitions will also be replaced
03457         it->e = it->e->searchReplaceAll(search, replace, ch);
03458         change |= ch;
03459     }
03460     return change;
03461 }
03462 bool ImplicitAssign::searchAndReplace(Exp* search, Exp* replace, bool cc) {
03463     bool change;
03464     lhs = lhs->searchReplaceAll(search, replace, change);
03465     return change;
03466 }
03467 
03468 void Assign::generateCode(HLLCode *hll, BasicBlock *pbb, int indLevel) {
03469     hll->AddAssignmentStatement(indLevel, this);
03470 }
03471 
03472 
03473 int Assign::getMemDepth() {
03474     int d1 = lhs->getMemDepth();
03475     int d2 = rhs->getMemDepth();
03476     if (d1 >= d2) return d1;
03477     return d2;
03478 }
03479 
03480 // PhiExp and ImplicitExp:
03481 bool Assignment::usesExp(Exp* e) {
03482     Exp *where = 0;
03483     return (lhs->isMemOf() || lhs->isRegOf()) && ((Unary*)lhs)->getSubExp1()->search(e, where);
03484 }
03485 
03486 bool Assign::usesExp(Exp *e) {
03487     Exp *where = 0;
03488     return (rhs->search(e, where) || ((lhs->isMemOf() || lhs->isRegOf()) && 
03489         ((Unary*)lhs)->getSubExp1()->search(e, where)));
03490 }
03491 
03492 #if 0
03493 bool Assign::match(const char *pattern, std::map<std::string, Exp*> &bindings)
03494 {
03495     if (strstr(pattern, ":=") == NULL)
03496         return false;
03497     char *left = strdup(pattern);
03498     char *right = strstr(left, ":=");
03499     *right++ = 0;
03500     right++;
03501     while (*right == ' ')
03502         right++;
03503     char *endleft = left + strlen(left) - 1;
03504     while (*endleft == ' ') {
03505         *endleft = 0;
03506         endleft--;
03507     }
03508 
03509     return lhs->match(left, bindings) && rhs->match(right, bindings);
03510 }
03511 
03512 void addPhiReferences(StatementSet &stmts, Statement *def);
03513 
03514 void addSimpleCopyReferences(StatementSet &stmts, Statement *def)
03515 {
03516     if (!(*((Assign*)def)->getLeft() == *((Assign*)def)->getRight()->getSubExp1()))
03517         return;
03518     Statement *copy = ((RefExp*)((Assign*)def)->getRight())->getDef();
03519     if (!stmts.exists(copy)) {
03520         stmts.insert(copy);
03521         if (copy->isPhi())
03522             addPhiReferences(stmts, copy);
03523         else if (copy->isAssign() && ((Assign*)copy)->getRight()->isSubscript())
03524             addSimpleCopyReferences(stmts, copy);
03525     }
03526 }
03527 
03528 void addPhiReferences(StatementSet &stmts, Statement *def)
03529 {
03530     PhiAssign *p = (PhiAssign*)def;
03531     for (PhiAssign::iterator it = p->begin(); it != p->end(); it++) {
03532         if ((*it).def->isPhi() && !stmts.exists((*it).def)) {
03533             stmts.insert((*it).def);
03534             addPhiReferences(stmts, (*it).def);
03535         } else if ((*it).def->isAssign() && ((Assign*)(*it).def)->getRight()->isSubscript()) {
03536             stmts.insert((*it).def);
03537             addSimpleCopyReferences(stmts, (*it).def);
03538         } else 
03539             stmts.insert((*it).def);
03540     }
03541 }
03542 #endif
03543 
03544 void Assignment::genConstraints(LocationSet& cons) {
03545     // Almost every assignment has at least a size from decoding
03546     // MVE: do/will PhiAssign's have a valid type? Why not?
03547     if (type)
03548         cons.insert(new Binary(opEquals,
03549             new Unary(opTypeOf,
03550                 new RefExp(lhs, this)),
03551             new TypeVal(type)));
03552 }
03553 
03554 // generate constraints
03555 void Assign::genConstraints(LocationSet& cons) {
03556     Assignment::genConstraints(cons);   // Gen constraint for the LHS
03557     Exp* con = rhs->genConstraints(
03558         new Unary(opTypeOf,
03559             new RefExp(lhs->clone(), this)));
03560     if (con) cons.insert(con);
03561 }
03562 
03563 void PhiAssign::genConstraints(LocationSet& cons) {
03564     // Generate a constraints st that all the phi's have to be the same type as
03565     // result
03566     Exp* result = new Unary(opTypeOf, new RefExp(lhs, this));
03567     Definitions::iterator uu;
03568     for (uu = defVec.begin(); uu != defVec.end(); uu++) {
03569         Exp* conjunct = new Binary(opEquals,
03570             result,
03571             new Unary(opTypeOf,
03572                 new RefExp(uu->e, uu->def)));
03573         cons.insert(conjunct);
03574     }
03575 }
03576 
03577 void CallStatement::genConstraints(LocationSet& cons) {
03578     Proc* dest = getDestProc();
03579     if (dest == NULL) return;
03580     Signature* destSig = dest->getSignature();
03581     // Generate a constraint for the type of each actual argument to be equal to the type of each formal parameter
03582     // (hopefully, these are already calculated correctly; if not, we need repeat till no change)
03583     StatementList::iterator aa;
03584     int p = 0;
03585     for (aa = arguments.begin(); aa != arguments.end(); ++aa, ++p) {
03586         Exp* arg = ((Assign*)*aa)->getRight();
03587         // Handle a[m[x]]
03588         if (arg->isAddrOf()) {
03589             Exp* sub = arg->getSubExp1();
03590             if (sub->isSubscript())
03591                 sub = ((RefExp*)sub)->getSubExp1();
03592             if (sub->isMemOf())
03593                 arg = ((Location*)sub)->getSubExp1();
03594         }
03595         if (arg->isRegOf() || arg->isMemOf() || arg->isSubscript() || arg->isLocal() || arg->isGlobal()) {
03596             Exp* con = new Binary(opEquals,
03597                 new Unary(opTypeOf, arg->clone()),
03598                 new TypeVal(destSig->getParamType(p)->clone()));
03599             cons.insert(con);
03600         }
03601     }
03602 
03603     if (dest->isLib()) {
03604         // A library procedure... check for two special cases
03605         std::string name = dest->getName();
03606         // Note: might have to chase back via a phi statement to get a sample
03607         // string
03608         char* str;
03609         Exp* arg0 = ((Assign*)*arguments.begin())->getRight();
03610         if ((name == "printf" || name == "scanf") && (str = arg0->getAnyStrConst()) != NULL) {
03611             // actually have to parse it
03612             int n = 1;      // Number of %s plus 1 = number of args
03613             char* p = str;
03614             while ((p = strchr(p, '%'))) {
03615                 p++;
03616                 Type* t = NULL;
03617                 int longness = 0;
03618                 bool sign = true;
03619                 bool cont;
03620                 do {
03621                     cont = false;
03622                     switch(*p) {
03623                         case 'u':
03624                             sign = false;
03625                             cont = true;
03626                             break;
03627                         case 'x':
03628                             sign = false;
03629                             // Fall through
03630                         case 'i':
03631                         case 'd': {
03632                             int size = 32;
03633                             // Note: the following only works for 32 bit code or where sizeof(long) == sizeof(int)
03634                             if (longness == 2) size = 64;
03635                             t = new IntegerType(size, sign);
03636                             break;
03637                         }
03638                         case 'f':
03639                         case 'g':
03640                             t = new FloatType(64);
03641                             break;
03642                         case 's':
03643                             t = new PointerType(new CharType());
03644                             break;
03645                         case 'l':
03646                             longness++;
03647                             cont = true;
03648                             break;
03649                         case '.':
03650                             cont = true;
03651                             break;
03652                         case '*':
03653                             assert(0);  // Star format not handled yet
03654                         default:
03655                             if (*p >= '0' && *p <= '9')
03656                                 cont = true;
03657                             break;
03658                     }
03659                     p++;
03660                 } while (cont);
03661                 if (t) {
03662                     // scanf takes addresses of these
03663                     if (name == "scanf")
03664                         t = new PointerType(t);
03665                     // Generate a constraint for the parameter
03666                     TypeVal* tv = new TypeVal(t);
03667                     StatementList::iterator aa = arguments.begin();
03668                     my_advance(aa, n);
03669                     Exp* argn = ((Assign*)*aa)->getRight();
03670                     Exp* con = argn->genConstraints(tv);
03671                     cons.insert(con);
03672                 }
03673                 n++;
03674             }
03675         }
03676     }
03677 }
03678 
03679 void BranchStatement::genConstraints(LocationSet& cons) {
03680     if (pCond == NULL && VERBOSE) {
03681         LOG << "Warning: BranchStatment " << number << " has no condition expression!\n";
03682         return;
03683     }
03684     Type* opsType;
03685     if (bFloat)
03686         opsType = new FloatType(0);
03687     else
03688         opsType = new IntegerType(0);
03689     if (  jtCond == BRANCH_JUGE || jtCond == BRANCH_JULE ||
03690           jtCond == BRANCH_JUG || jtCond == BRANCH_JUL) {
03691         assert(!bFloat);
03692         ((IntegerType*)opsType)->bumpSigned(-1);
03693     } else if (jtCond == BRANCH_JSGE || jtCond == BRANCH_JSLE ||
03694                jtCond == BRANCH_JSG  || jtCond == BRANCH_JSL) {
03695         assert(!bFloat);
03696         ((IntegerType*)opsType)->bumpSigned(+1);
03697     }
03698 
03699     // Constraints leading from the condition
03700     assert(pCond->getArity() == 2);
03701     Exp* a = ((Binary*)pCond)->getSubExp1();
03702     Exp* b = ((Binary*)pCond)->getSubExp2();
03703     // Generate constraints for a and b separately (if any).  Often only need a size, since we get basic type and
03704     // signedness from the branch condition (e.g. jump if unsigned less)
03705     Exp* Ta; Exp* Tb;
03706     if (a->isSizeCast()) {
03707         opsType->setSize(((Const*)((Binary*)a)->getSubExp1())->getInt());
03708         Ta = new Unary(opTypeOf, ((Binary*)a)->getSubExp2());
03709     } else
03710         Ta = new Unary(opTypeOf, a);
03711     if (b->isSizeCast()) {
03712         opsType->setSize(((Const*)((Binary*)b)->getSubExp1())->getInt());
03713         Tb = new Unary(opTypeOf, ((Binary*)b)->getSubExp2());
03714     } else
03715         Tb = new Unary(opTypeOf, b);
03716     // Constrain that Ta == opsType and Tb == opsType
03717     Exp* con = new Binary(opEquals, Ta, new TypeVal(opsType));
03718     cons.insert(con);
03719          con = new Binary(opEquals, Tb, new TypeVal(opsType));
03720     cons.insert(con);
03721 }
03722 
03723 int Statement::setConscripts(int n) {
03724     StmtConscriptSetter scs(n, false);
03725     accept(&scs);
03726     return scs.getLast();
03727 }
03728 
03729 void Statement::clearConscripts() {
03730     StmtConscriptSetter scs(0, true);
03731     accept(&scs);
03732 }
03733 
03734 // Cast the constant num to be of type ty. Return true if a change made
03735 bool Statement::castConst(int num, Type* ty) {
03736     ExpConstCaster ecc(num, ty);
03737     StmtModifier scc(&ecc);
03738     accept(&scc);
03739     return ecc.isChanged();
03740 }
03741 
03742 void Statement::stripSizes() {
03743     SizeStripper ss;
03744     StmtModifier sm(&ss);
03745     accept(&sm);
03746 }
03747 
03748 // Visiting from class StmtExpVisitor
03749 // Visit all the various expressions in a statement
03750 bool Assign::accept(StmtExpVisitor* v) {
03751     bool override;
03752     bool ret = v->visit(this, override);
03753     if (override)
03754         // The visitor has overridden this functionality.  This is needed for example in UsedLocFinder, where the lhs of
03755         // an assignment is not used (but if it's m[blah], then blah is used)
03756         return ret;
03757     if (ret && lhs) ret = lhs->accept(v->ev);
03758     if (ret && rhs) ret = rhs->accept(v->ev);
03759     return ret;
03760 }
03761 
03762 bool PhiAssign::accept(StmtExpVisitor* v) {
03763     bool override;
03764     bool ret = v->visit(this, override);
03765     if (override) return ret;
03766     if (ret && lhs) ret = lhs->accept(v->ev);
03767     iterator it;
03768     for (it = defVec.begin(); it != defVec.end(); ++it) {
03769         if (it->e == NULL) continue;
03770         RefExp* re = new RefExp(it->e, it->def);
03771         ret = re->accept(v->ev);
03772         if (ret == false) return false;
03773     }
03774     return true;
03775 }
03776 
03777 bool ImplicitAssign::accept(StmtExpVisitor* v) {
03778     bool override;
03779     bool ret = v->visit(this, override);
03780     if (override) return ret;
03781     if (ret && lhs) ret = lhs->accept(v->ev);
03782     return ret;
03783 }
03784 
03785 
03786 bool GotoStatement::accept(StmtExpVisitor* v) {
03787     bool override;
03788     bool ret = v->visit(this, override);
03789     if (override) return ret;
03790     if (ret && pDest)
03791         ret = pDest->accept(v->ev);
03792     return ret;
03793 }
03794 
03795 bool BranchStatement::accept(StmtExpVisitor* v) {
03796     bool override;
03797     bool ret = v->visit(this, override);
03798     if (override) return ret;
03799     // Destination will always be a const for X86, so the below will never be used in practice
03800     if (ret && pDest)
03801         ret = pDest->accept(v->ev);
03802     if (ret && pCond)
03803         ret = pCond->accept(v->ev);
03804     return ret;
03805 }
03806 
03807 bool CaseStatement::accept(StmtExpVisitor* v) {
03808     bool override;
03809     bool ret = v->visit(this, override);
03810     if (override) return ret;
03811     if (ret && pDest)
03812         ret = pDest->accept(v->ev);
03813     if (ret && pSwitchInfo && pSwitchInfo->pSwitchVar)
03814         ret = pSwitchInfo->pSwitchVar->accept(v->ev);
03815     return ret;
03816 }
03817 
03818 bool CallStatement::accept(StmtExpVisitor* v) {
03819     bool override;
03820     bool ret = v->visit(this, override);
03821     if (override) return ret;
03822     if (ret && pDest)
03823         ret = pDest->accept(v->ev);
03824     StatementList::iterator it;
03825     for (it = arguments.begin(); ret && it != arguments.end(); it++)
03826         ret = (*it)->accept(v);
03827     // FIXME: why aren't defines counted?
03828 #if 0       // Do we want to accept visits to the defines? Not sure now...
03829     std::vector<ReturnInfo>::iterator rr;
03830     for (rr = defines.begin(); ret && rr != defines.end(); rr++)
03831         if (rr->e)          // Can be NULL now to line up with other returns
03832             ret = rr->e->accept(v->ev);
03833 #endif
03834     // FIXME: surely collectors should be counted?
03835     return ret;
03836 }
03837 
03838 bool ReturnStatement::accept(StmtExpVisitor* v) {
03839     bool override;
03840     ReturnStatement::iterator rr;
03841     if (!v->visit(this, override))
03842         return false;
03843     if (override) return true;
03844     if (!v->isIgnoreCol()) {
03845         DefCollector::iterator dd;
03846         for (dd = col.begin(); dd != col.end(); ++dd)
03847             if (!(*dd)->accept(v))
03848                 return false;
03849         // EXPERIMENTAL: for now, count the modifieds as if they are a collector (so most, if not all of the time,
03850         // ignore them). This is so that we can detect better when a definition is used only once, and therefore
03851         // propagate anything to it
03852         for (rr = modifieds.begin(); rr != modifieds.end(); ++rr)
03853             if (!(*rr)->accept(v))
03854                 return false;
03855     }
03856     for (rr = returns.begin(); rr != returns.end(); ++rr)
03857         if (!(*rr)->accept(v))
03858             return false;
03859     return true;
03860 }
03861 
03862 bool BoolAssign::accept(StmtExpVisitor* v) {
03863     bool override;
03864     bool ret = v->visit(this, override);
03865     if (override) return ret;
03866     if (ret && pCond)
03867         ret = pCond->accept(v->ev);
03868     return ret;
03869 }
03870 
03871 // Visiting from class StmtModifier
03872 // Modify all the various expressions in a statement
03873 bool Assign::accept(StmtModifier* v) {
03874     bool recur;
03875     v->visit(this, recur);
03876     v->mod->clearMod();
03877     if (recur) lhs = lhs->accept(v->mod);
03878     if (recur) rhs = rhs->accept(v->mod);
03879     if (VERBOSE && v->mod->isMod())
03880         LOG << "Assignment changed: now " << this << "\n";
03881     return true;
03882 }
03883 bool PhiAssign::accept(StmtModifier* v) {
03884     bool recur;
03885     v->visit(this, recur);
03886     v->mod->clearMod();
03887     if (recur) lhs = lhs->accept(v->mod);
03888     if (VERBOSE && v->mod->isMod())
03889         LOG << "PhiAssign changed: now " << this << "\n";
03890     return true;
03891 }
03892 
03893 bool ImplicitAssign::accept(StmtModifier* v) {
03894     bool recur;
03895     v->visit(this, recur);
03896     v->mod->clearMod();
03897     if (recur) lhs = lhs->accept(v->mod);
03898     if (VERBOSE && v->mod->isMod())
03899         LOG << "ImplicitAssign changed: now " << this << "\n";
03900     return true;
03901 }
03902 
03903 bool BoolAssign::accept(StmtModifier* v) {
03904     bool recur;
03905     v->visit(this, recur);
03906     if (pCond && recur)
03907         pCond = pCond->accept(v->mod);
03908     if (recur && lhs->isMemOf()) {
03909         ((Location*)lhs)->setSubExp1(((Location*)lhs)->getSubExp1()->accept(v->mod));
03910     }
03911     return true;
03912 }
03913 
03914 
03915 bool GotoStatement::accept(StmtModifier* v) {
03916     bool recur;
03917     v->visit(this, recur);
03918     if (pDest && recur)
03919         pDest = pDest->accept(v->mod);
03920     return true;
03921 }
03922 
03923 bool BranchStatement::accept(StmtModifier* v) {
03924     bool recur;
03925     v->visit(this, recur);
03926     if (pDest && recur)
03927         pDest = pDest->accept(v->mod);
03928     if (pCond && recur)
03929         pCond = pCond->accept(v->mod);
03930     return true;
03931 }
03932 
03933 bool CaseStatement::accept(StmtModifier* v) {
03934     bool recur;
03935     v->visit(this, recur);
03936     if (pDest && recur)
03937         pDest = pDest->accept(v->mod);
03938     if (pSwitchInfo && pSwitchInfo->pSwitchVar && recur)
03939         pSwitchInfo->pSwitchVar = pSwitchInfo->pSwitchVar->accept(v->mod);
03940     return true;
03941 }
03942 
03943 bool CallStatement::accept(StmtModifier* v) {
03944     bool recur;
03945     v->visit(this, recur);
03946     if (!recur) return true;
03947     if (pDest)
03948         pDest = pDest->accept(v->mod);
03949     StatementList::iterator it;
03950     for (it = arguments.begin(); recur && it != arguments.end(); it++)
03951         (*it)->accept(v);
03952     // For example: needed for CallBypasser so that a collected definition that happens to be another call gets
03953     // adjusted
03954     // I'm thinking no at present... let the bypass and propagate while possible logic take care of it, and leave the
03955     // collectors as the rename logic set it
03956     // Well, sort it out with ignoreCollector()
03957     if (!v->ignoreCollector()) {
03958         DefCollector::iterator cc;
03959         for (cc = defCol.begin(); cc != defCol.end(); cc++)
03960             (*cc)->accept(v);
03961     }
03962     StatementList::iterator dd;
03963     for (dd = defines.begin(); recur && dd != defines.end(); ++dd)
03964         (*dd)->accept(v);
03965     return true;
03966 }
03967 
03968 bool ReturnStatement::accept(StmtModifier* v) {
03969     bool recur;
03970     v->visit(this, recur);
03971     if (!recur) return true;
03972     if (!v->ignoreCollector()) {
03973         DefCollector::iterator dd;
03974         for (dd = col.begin(); dd != col.end(); ++dd)
03975             if (!(*dd)->accept(v))
03976                 return false;
03977     }
03978     ReturnStatement::iterator rr;
03979     for (rr = modifieds.begin(); rr != modifieds.end(); ++rr)
03980         if (!(*rr)->accept(v))
03981             return false;
03982     for (rr = returns.begin(); rr != returns.end(); ++rr)
03983         if (!(*rr)->accept(v))
03984             return false;
03985     return true;
03986 }
03987 
03988 // Visiting from class StmtPartModifier
03989 // Modify all the various expressions in a statement, except for the top level of the LHS of assignments
03990 bool Assign::accept(StmtPartModifier* v) {
03991     bool recur;
03992     v->visit(this, recur);
03993     v->mod->clearMod();
03994     if (recur && lhs->isMemOf()) {
03995         ((Location*)lhs)->setSubExp1(((Location*)lhs)->getSubExp1()->accept(v->mod));
03996     }
03997     if (recur) rhs = rhs->accept(v->mod);
03998     if (VERBOSE && v->mod->isMod())
03999         LOG << "Assignment changed: now " << this << "\n";
04000     return true;
04001 }
04002 bool PhiAssign::accept(StmtPartModifier* v) {
04003     bool recur;
04004     v->visit(this, recur);
04005     v->mod->clearMod();
04006     if (recur && lhs->isMemOf()) {
04007         ((Location*)lhs)->setSubExp1(((Location*)lhs)->getSubExp1()->accept(v->mod));
04008     }
04009     if (VERBOSE && v->mod->isMod())
04010         LOG << "PhiAssign changed: now " << this << "\n";
04011     return true;
04012 }
04013 
04014 bool ImplicitAssign::accept(StmtPartModifier* v) {
04015     bool recur;
04016     v->visit(this, recur);
04017     v->mod->clearMod();
04018     if (recur && lhs->isMemOf()) {
04019         ((Location*)lhs)->setSubExp1(((Location*)lhs)->getSubExp1()->accept(v->mod));
04020     }
04021     if (VERBOSE && v->mod->isMod())
04022         LOG << "ImplicitAssign changed: now " << this << "\n";
04023     return true;
04024 }
04025 
04026 
04027 bool GotoStatement::accept(StmtPartModifier* v) {
04028     bool recur;
04029     v->visit(this, recur);
04030     if (pDest && recur)
04031         pDest = pDest->accept(v->mod);
04032     return true;
04033 }
04034 
04035 bool BranchStatement::accept(StmtPartModifier* v) {
04036     bool recur;
04037     v->visit(this, recur);
04038     if (pDest && recur)
04039         pDest = pDest->accept(v->mod);
04040     if (pCond && recur)
04041         pCond = pCond->accept(v->mod);
04042     return true;
04043 }
04044 
04045 bool CaseStatement::accept(StmtPartModifier* v) {
04046     bool recur;
04047     v->visit(this, recur);
04048     if (pDest && recur)
04049         pDest = pDest->accept(v->mod);
04050     if (pSwitchInfo && pSwitchInfo->pSwitchVar && recur)
04051         pSwitchInfo->pSwitchVar = pSwitchInfo->pSwitchVar->accept(v->mod);
04052     return true;
04053 }
04054 
04055 bool CallStatement::accept(StmtPartModifier* v) {
04056     bool recur;
04057     v->visit(this, recur);
04058     if (pDest && recur)
04059         pDest = pDest->accept(v->mod);
04060     StatementList::iterator it;
04061     for (it = arguments.begin(); recur && it != arguments.end(); it++)
04062         (*it)->accept(v);
04063     // For example: needed for CallBypasser so that a collected definition that happens to be another call gets
04064     // adjusted
04065     // But now I'm thinking no, the bypass and propagate while possible logic should take care of it.
04066     // Then again, what about the use collectors in calls? Best to do it.
04067     if (!v->ignoreCollector()) {
04068         DefCollector::iterator dd;
04069         for (dd = defCol.begin(); dd != defCol.end(); dd++)
04070             (*dd)->accept(v);
04071         UseCollector::iterator uu;
04072         for (uu = useCol.begin(); uu != useCol.end(); ++uu)
04073             // I believe that these should never change at the top level, e.g. m[esp{30} + 4] -> m[esp{-} - 20]
04074             (*uu)->accept(v->mod);
04075     }
04076     StatementList::iterator dd;
04077     for (dd = defines.begin(); recur && dd != defines.end(); dd++)
04078         (*dd)->accept(v);
04079     return true;
04080 }
04081 
04082 bool ReturnStatement::accept(StmtPartModifier* v) {
04083     bool recur;
04084     v->visit(this, recur);
04085     ReturnStatement::iterator rr;
04086     for (rr = modifieds.begin(); rr != modifieds.end(); ++rr)
04087         if (!(*rr)->accept(v))
04088             return false;
04089     for (rr = returns.begin(); rr != returns.end(); ++rr)
04090         if (!(*rr)->accept(v))
04091             return false;
04092     return true;
04093 }
04094 
04095 bool BoolAssign::accept(StmtPartModifier* v) {
04096     bool recur;
04097     v->visit(this, recur);
04098     if (pCond && recur)
04099         pCond = pCond->accept(v->mod);
04100     if (lhs && recur)
04101         lhs = lhs->accept(v->mod);
04102     return true;
04103 }
04104 
04105 // Fix references to the returns of call statements
04106 void Statement::bypass() {
04107     CallBypasser cb(this);
04108     StmtPartModifier sm(&cb);           // Use the Part modifier so we don't change the top level of LHS of assigns etc
04109     accept(&sm);
04110     if (cb.isTopChanged())
04111         simplify();                     // E.g. m[esp{20}] := blah -> m[esp{-}-20+4] := blah
04112 }
04113 
04114 // Find the locations used by expressions in this Statement.
04115 // Use the StmtExpVisitor and UsedLocsFinder visitor classes
04116 // cc = count collectors
04117 void Statement::addUsedLocs(LocationSet& used, bool cc /* = false */, bool memOnly /*= false */) {
04118     UsedLocsFinder ulf(used, memOnly);
04119     UsedLocsVisitor ulv(&ulf, cc);
04120     accept(&ulv);
04121 }
04122 
04123 bool Statement::addUsedLocals(LocationSet& used) {
04124     UsedLocalFinder ulf(used, proc);
04125     UsedLocsVisitor ulv(&ulf, false);
04126     accept(&ulv);
04127     return ulf.wasAllFound();
04128 }
04129 
04130 // For all expressions in this Statement, replace any e with e{def}
04131 void Statement::subscriptVar(Exp* e, Statement* def /*, Cfg* cfg */) {
04132     ExpSubscripter es(e, def /*, cfg*/);
04133     StmtSubscripter ss(&es);
04134     accept(&ss);
04135 }
04136 
04137 // Find all constants in this Statement
04138 void Statement::findConstants(std::list<Const*>& lc) {
04139     ConstFinder cf(lc);
04140     StmtConstFinder scf(&cf);
04141     accept(&scf);
04142 }
04143 
04144 // Convert this PhiAssignment to an ordinary Assignment.  Hopefully, this is the only place that Statements change from
04145 // one class to another.  All throughout the code, we assume that the addresses of Statement objects do not change,
04146 // so we need this slight hack to overwrite one object with another
04147 void PhiAssign::convertToAssign(Exp* rhs) {
04148     // I believe we always want to propagate to these ex-phi's; check!:
04149     rhs = rhs->propagateAll();
04150     // Thanks to tamlin for this cleaner way of implementing this hack
04151     assert(sizeof(Assign) <= sizeof(PhiAssign)); 
04152     int n = number;                                 // These items disappear with the destructor below
04153     PBB bb = pbb;
04154     UserProc* p = proc;
04155     Exp* lhs_ = lhs;
04156     Exp* rhs_ = rhs;
04157     Type* type_ = type;
04158     this->~PhiAssign();                             // Explicitly destroy this, but keep the memory allocated.
04159     Assign* a = new(this) Assign(type_, lhs_, rhs_);// construct in-place. Note that 'a' == 'this' 
04160     a->setNumber(n); 
04161     a->setProc(p); 
04162     a->setBB(bb); 
04163 //  RTL* rtl = bb->getRTLWithStatement(this);
04164 //  if (rtl->getAddress() == 0)
04165 //      rtl->setAddress(1);             // Strange things happen to real assignments with address 0
04166 }
04167 
04168 void PhiAssign::simplify() {
04169     lhs = lhs->simplify();
04170 
04171     if (defVec.begin() != defVec.end()) {
04172         Definitions::iterator uu;
04173         bool allSame = true;
04174         uu = defVec.begin();
04175         Statement* first;
04176         for (first = (uu++)->def; uu != defVec.end(); uu++) {
04177             if (uu->def != first) {
04178                 allSame = false;
04179                 break;
04180             }
04181         }
04182 
04183         if (allSame) {
04184             if (VERBOSE)
04185                 LOG << "all the same in " << this << "\n";
04186             convertToAssign(new RefExp(lhs, first));
04187             return;
04188         }
04189 
04190         bool onlyOneNotThis = true;
04191         Statement *notthis = (Statement*)-1;
04192         for (uu = defVec.begin(); uu != defVec.end(); uu++) {
04193             if (uu->def == NULL || uu->def->isImplicit() || !uu->def->isPhi() || uu->def != this)
04194                 if (notthis != (Statement*)-1) {
04195                     onlyOneNotThis = false;
04196                     break;
04197                 } else notthis = uu->def;
04198         }
04199 
04200         if (onlyOneNotThis && notthis != (Statement*)-1) {
04201             if (VERBOSE)
04202                 LOG << "all but one not this in " << this << "\n";
04203             convertToAssign(new RefExp(lhs, notthis));
04204             return;
04205         }
04206     }
04207 }
04208 
04209 void PhiAssign::putAt(int i, Statement* def, Exp* e) {
04210     assert(e); // should be something surely
04211     if (i >= (int)defVec.size())
04212         defVec.resize(i+1);     // Note: possible to insert uninitialised elements
04213     defVec[i].def = def;
04214     defVec[i].e = e;
04215 }
04216 
04217 void CallStatement::setLeftFor(Exp* forExp, Exp* newExp) {
04218     std::cerr << "! Attempt to setLeftFor this call statement! forExp is " << forExp << ", newExp is " << newExp <<
04219         "\n";
04220     assert(0);
04221 }
04222 
04223 bool Assignment::definesLoc(Exp* loc) {
04224     if (lhs->getOper() == opAt)                 // For foo@[x:y], match of foo==loc OR whole thing == loc
04225         if (*((Ternary*)lhs)->getSubExp1() == *loc) return true;
04226     return *lhs == *loc;
04227 }
04228 
04229 bool CallStatement::definesLoc(Exp* loc) {
04230     StatementList::iterator dd;
04231     for (dd = defines.begin(); dd != defines.end(); ++dd) {
04232         Exp* lhs = ((Assign*)*dd)->getLeft();
04233         if (*lhs == *loc)
04234             return true;
04235     }
04236     return false;
04237 }
04238 
04239 // Does a ReturnStatement define anything? Not really, the locations are already defined earlier in the procedure.
04240 // However, nothing comes after the return statement, so it doesn't hurt to pretend it does, and this is a place to
04241 // store the return type(s) for example.
04242 // FIXME: seems it would be cleaner to say that Return Statements don't define anything.
04243 bool ReturnStatement::definesLoc(Exp* loc) {
04244     iterator it;
04245     for (it = modifieds.begin(); it != modifieds.end(); it++) {
04246         if ((*it)->definesLoc(loc))
04247             return true;
04248     }
04249     return false;
04250 }
04251 
04252 // FIXME: see above
04253 void ReturnStatement::getDefinitions(LocationSet& ls) {
04254     iterator rr;
04255     for (rr = modifieds.begin(); rr != modifieds.end(); ++rr)
04256         (*rr)->getDefinitions(ls);
04257 }
04258 
04259 Type* ReturnStatement::getTypeFor(Exp* e) {
04260     ReturnStatement::iterator rr;
04261     for (rr = modifieds.begin(); rr != modifieds.end(); rr++) {
04262         if (*((Assignment*)*rr)->getLeft() == *e)
04263             return ((Assignment*)*rr)->getType();
04264     }
04265     return NULL;
04266 }
04267 
04268 void ReturnStatement::setTypeFor(Exp*e, Type* ty) {
04269     ReturnStatement::iterator rr;
04270     for (rr = modifieds.begin(); rr != modifieds.end(); rr++) {
04271         if (*((Assignment*)*rr)->getLeft() == *e) {
04272             ((Assignment*)*rr)->setType(ty);
04273             break;
04274         }
04275     }
04276     for (rr = returns.begin(); rr != returns.end(); rr++) {
04277         if (*((Assignment*)*rr)->getLeft() == *e) {
04278             ((Assignment*)*rr)->setType(ty);
04279             return;
04280         }
04281     }
04282 }
04283 
04284 #define RETSTMT_COLS 120
04285 void ReturnStatement::print(std::ostream& os, bool html) {
04286     os << std::setw(4) << std::dec << number << " ";
04287     if (html) {
04288         os << "</td><td>";
04289         os << "<a name=\"stmt" << std::dec << number << "\">";
04290     }
04291     os << "RET";
04292     iterator it;
04293     bool first = true;
04294     unsigned column = 19;
04295     for (it = returns.begin(); it != returns.end(); ++it) {
04296         std::ostringstream ost;
04297         ((Assignment*)*it)->printCompact(ost, html);
04298         unsigned len = ost.str().length();
04299         if (first) {
04300             first = false;
04301             os << " ";
04302         } else if (column + 4 + len > RETSTMT_COLS) {   // 4 for command 3 spaces
04303             if (column != RETSTMT_COLS-1) os << ",";    // Comma at end of line
04304             os << "\n                ";
04305             column = 16;
04306         } else {
04307             os << ",   ";
04308             column += 4;
04309         }
04310         os << ost.str().c_str();
04311         column += len;
04312     }
04313     if (html)
04314         os << "</a><br>";
04315     else
04316         os << "\n              ";
04317     os << "Modifieds: ";
04318     first = true;
04319     column = 25;
04320     for (it = modifieds.begin(); it != modifieds.end(); ++it) {
04321         std::ostringstream ost;
04322         Assign* as = (Assign*)*it;
04323         Type* ty = as->getType();
04324         if (ty)
04325             ost << "*" << ty << "* ";
04326         ost << as->getLeft();
04327         unsigned len = ost.str().length();
04328         if (first)
04329             first = false;
04330         else if (column + 3 + len > RETSTMT_COLS) {     // 3 for comma and 2 spaces
04331             if (column != RETSTMT_COLS-1) os << ",";    // Comma at end of line
04332             os << "\n                ";
04333             column = 16;
04334         } else {
04335             os << ",  ";
04336             column += 3;
04337         }
04338         os << ost.str().c_str();
04339         column += len;
04340     }
04341 #if 1
04342     // Collected reaching definitions
04343     if (html)
04344         os << "<br>";
04345     else
04346         os << "\n              ";
04347     os << "Reaching definitions: ";
04348     col.print(os, html);
04349 #endif
04350 }
04351 
04352 // A helper class for comparing Assignment*'s sensibly
04353 bool lessAssignment::operator()(const Assignment* x, const Assignment* y) const {
04354     Assignment* xx = const_cast<Assignment*>(x);
04355     Assignment* yy = const_cast<Assignment*>(y);
04356     return (*xx->getLeft() < *yy->getLeft());       // Compare the LHS expressions
04357 }
04358 
04359 // Repeat the above for Assign's; sometimes the compiler doesn't (yet) understand that Assign's are Assignment's
04360 bool lessAssign::operator()(const Assign* x, const Assign* y) const {
04361     Assign* xx = const_cast<Assign*>(x);
04362     Assign* yy = const_cast<Assign*>(y);
04363     return (*xx->getLeft() < *yy->getLeft());       // Compare the LHS expressions
04364 }
04365 
04366 // Update the modifieds, in case the signature and hence ordering and filtering has changed, or the locations in the
04367 // collector have changed. Does NOT remove preserveds (deferred until updating returns).
04368 void ReturnStatement::updateModifieds() {
04369     Signature* sig = proc->getSignature();
04370     StatementList oldMods(modifieds);                   // Copy the old modifieds
04371     modifieds.clear();
04372 
04373     if (pbb->getNumInEdges() == 1 && pbb->getInEdges()[0]->getLastStmt()->isCall()) {
04374         CallStatement *call = (CallStatement*)pbb->getInEdges()[0]->getLastStmt();
04375         if (call->getDestProc() && FrontEnd::noReturnCallDest(call->getDestProc()->getName()))
04376             return;
04377     }
04378     // For each location in the collector, make sure that there is an assignment in the old modifieds, which will
04379     // be filtered and sorted to become the new modifieds
04380     // Ick... O(N*M) (N existing modifeds, M collected locations)
04381     DefCollector::iterator ll;
04382     StatementList::iterator it;
04383     for (ll = col.begin(); ll != col.end(); ++ll) {
04384         bool found = false;
04385         Assign* as = (Assign*)*ll;
04386         Exp* colLhs = as->getLeft();
04387         if (proc->filterReturns(colLhs))
04388             continue;                                   // Filtered out
04389         for (it = oldMods.begin(); it != oldMods.end(); it++) {
04390             Exp* lhs = ((Assign*)*it)->getLeft();
04391             if (*lhs == *colLhs) {
04392                 found = true;
04393                 break;
04394             }
04395         }
04396         if (!found) {
04397             ImplicitAssign* ias = new ImplicitAssign(
04398                 as->getType()->clone(),
04399                 as->getLeft()->clone());
04400             ias->setProc(proc);                         // Comes from the Collector
04401             ias->setBB(pbb);
04402             oldMods.append(ias);
04403         }
04404     }
04405 
04406     // Mostly the old modifications will be in the correct order, and inserting will be fastest near the start of the
04407     // new list. So read the old modifications in reverse order
04408     for (it = oldMods.end(); it != oldMods.begin(); ) {
04409         --it;                                       // Becuase we are using a forwards iterator backwards
04410         // Make sure the LHS is still in the collector
04411         Assign* as = (Assign*)*it;
04412         Exp* lhs = as->getLeft();
04413         if (!col.existsOnLeft(lhs))
04414             continue;                       // Not in collector: delete it (don't copy it)
04415         if (proc->filterReturns(lhs))
04416             continue;                       // Filtered out: delete it
04417     
04418         // Insert as, in order, into the existing set of modifications
04419         StatementList::iterator nn;
04420         bool inserted = false;
04421         for (nn = modifieds.begin(); nn != modifieds.end(); ++nn) {
04422             if (sig->returnCompare(*as, *(Assign*)*nn)) {       // If the new assignment is less than the current one
04423                 nn = modifieds.insert(nn, as);                  // then insert before this position
04424                 inserted = true;
04425                 break;
04426             }
04427         }
04428         if (!inserted)
04429             modifieds.insert(modifieds.end(), as);  // In case larger than all existing elements
04430     }
04431 }
04432 
04433 // Update the returns, in case the signature and hence ordering and filtering has changed, or the locations in the
04434 // modifieds list
04435 void ReturnStatement::updateReturns() {
04436     Signature* sig = proc->getSignature();
04437     int sp = sig->getStackRegister();
04438     StatementList oldRets(returns);                 // Copy the old returns
04439     returns.clear();
04440     // For each location in the modifieds, make sure that there is an assignment in the old returns, which will
04441     // be filtered and sorted to become the new returns
04442     // Ick... O(N*M) (N existing returns, M modifieds locations)
04443     StatementList::iterator dd, it;
04444     for (dd = modifieds.begin(); dd != modifieds.end(); ++dd) {
04445         bool found = false;
04446         Exp* loc = ((Assignment*)*dd)->getLeft();
04447         if (proc->filterReturns(loc))
04448             continue;                                   // Filtered out
04449         // Special case for the stack pointer: it has to be a modified (otherwise, the changes will bypass the calls),
04450         // but it is not wanted as a return
04451         if (loc->isRegN(sp)) continue;
04452         for (it = oldRets.begin(); it != oldRets.end(); it++) {
04453             Exp* lhs = ((Assign*)*it)->getLeft();
04454             if (*lhs == *loc) {
04455                 found = true;
04456                 break;
04457             }
04458         }
04459         if (!found) {
04460             Exp* rhs = col.findDefFor(loc);         // Find the definition that reaches the return statement's collector
04461             Assign* as = new Assign(loc->clone(), rhs->clone());
04462             as->setProc(proc);
04463             as->setBB(pbb);
04464             oldRets.append(as);
04465         }
04466     }
04467 
04468     // Mostly the old returns will be in the correct order, and inserting will be fastest near the start of the
04469     // new list. So read the old returns in reverse order
04470     for (it = oldRets.end(); it != oldRets.begin(); ) {
04471         --it;                                       // Becuase we are using a forwards iterator backwards
04472         // Make sure the LHS is still in the modifieds
04473         Assign* as = (Assign*)*it;
04474         Exp* lhs = as->getLeft();
04475         if (!modifieds.existsOnLeft(lhs))
04476             continue;                       // Not in modifieds: delete it (don't copy it)
04477         if (proc->filterReturns(lhs))
04478             continue;                       // Filtered out: delete it
04479 #if 1
04480         // Preserveds are NOT returns (nothing changes, so what are we returning?)
04481         // Check if it is a preserved location, e.g. r29 := r29{-}
04482         Exp* rhs = as->getRight();
04483         if (rhs->isSubscript() && ((RefExp*)rhs)->isImplicitDef() && *((RefExp*)rhs)->getSubExp1() == *lhs)
04484             continue;                       // Filter out the preserveds
04485 #endif
04486             
04487         // Insert as, in order, into the existing set of returns
04488         StatementList::iterator nn;
04489         bool inserted = false;
04490         for (nn = returns.begin(); nn != returns.end(); ++nn) {
04491             if (sig->returnCompare(*as, *(Assign*)*nn)) {       // If the new assignment is less than the current one
04492                 nn = returns.insert(nn, as);                    // then insert before this position
04493                 inserted = true;
04494                 break;
04495             }
04496         }
04497         if (!inserted)
04498             returns.insert(returns.end(), as);  // In case larger than all existing elements
04499     }
04500 }
04501 
04502 // Set the defines to the set of locations modified by the callee, or if no callee, to all variables live at this call
04503 void CallStatement::updateDefines() {
04504     Signature* sig;
04505     if (procDest)
04506         // The signature knows how to order the returns
04507         sig = procDest->getSignature();
04508     else
04509         // Else just use the enclosing proc's signature
04510         sig = proc->getSignature();
04511 
04512     if (procDest && procDest->isLib()) {
04513         sig->setLibraryDefines(&defines);               // Set the locations defined
04514         return;
04515     } else if (Boomerang::get()->assumeABI) {
04516         // Risky: just assume the ABI caller save registers are defined
04517         Signature::setABIdefines(proc->getProg(), &defines);
04518         return;
04519     }
04520 
04521     // Move the defines to a temporary list
04522     StatementList oldDefines(defines);                  // Copy the old defines
04523     StatementList::iterator it;
04524     defines.clear();
04525 
04526     if (procDest && calleeReturn) {
04527         StatementList::iterator mm;
04528         StatementList& modifieds = ((UserProc*)procDest)->getModifieds();
04529         for (mm = modifieds.begin(); mm != modifieds.end(); ++mm) {
04530             Assign* as = (Assign*)*mm;
04531             Exp* loc = as->getLeft();
04532             if (proc->filterReturns(loc))
04533                 continue;
04534             Type* ty = as->getType();
04535             if (!oldDefines.existsOnLeft(loc))
04536                 oldDefines.append(new ImplicitAssign(ty, loc));
04537         }
04538     } else {
04539         // Ensure that everything in the UseCollector has an entry in oldDefines
04540         LocationSet::iterator ll;
04541         for (ll = useCol.begin(); ll != useCol.end(); ++ll) {
04542             Exp* loc = *ll;
04543             if (proc->filterReturns(loc))
04544                 continue;                                   // Filtered out
04545             if (!oldDefines.existsOnLeft(loc)) {
04546                 ImplicitAssign* as = new ImplicitAssign(loc->clone());
04547                 as->setProc(proc);
04548                 as->setBB(pbb);
04549                 oldDefines.append(as);
04550             }
04551         }
04552     }
04553 
04554     for (it = oldDefines.end(); it != oldDefines.begin(); ) {
04555         --it;                                       // Becuase we are using a forwards iterator backwards
04556         // Make sure the LHS is still in the return or collector
04557         Assign* as = (Assign*)*it;
04558         Exp* lhs = as->getLeft();
04559         if (calleeReturn) {
04560             if (!calleeReturn->definesLoc(lhs))
04561                 continue;                       // Not in callee returns
04562         } else {
04563             if (!useCol.exists(lhs))
04564                 continue;                       // Not in collector: delete it (don't copy it)
04565         }
04566         if (proc->filterReturns(lhs))
04567             continue;                       // Filtered out: delete it
04568 
04569         // Insert as, in order, into the existing set of definitions
04570         StatementList::iterator nn;
04571         bool inserted = false;
04572         for (nn = defines.begin(); nn != defines.end(); ++nn) {
04573             if (sig->returnCompare(*as, *(Assign*)*nn)) {   // If the new assignment is less than the current one
04574                 nn = defines.insert(nn, as);                // then insert before this position
04575                 inserted = true;
04576                 break;
04577             }
04578         }
04579         if (!inserted)
04580             defines.insert(defines.end(), as);  // In case larger than all existing elements
04581     }
04582 }
04583 
04584 // A helper class for updateArguments. It just dishes out a new argument from one of the three sources: the signature,
04585 // the callee parameters, or the defCollector in the call
04586 class ArgSourceProvider {
04587 enum Src {SRC_LIB, SRC_CALLEE, SRC_COL};
04588         Src         src;
04589         CallStatement* call;
04590         int         i, n;               // For SRC_LIB
04591         Signature*  callSig;
04592         StatementList::iterator pp;     // For SRC_CALLEE
04593         StatementList* calleeParams;
04594         DefCollector::iterator cc;      // For SRC_COL
04595         DefCollector* defCol;
04596 public:
04597                     ArgSourceProvider(CallStatement* call);
04598         Exp*        nextArgLoc();       // Get the next location (not subscripted)
04599         Type*       curType(Exp* e);    // Get the current location's type
04600         bool        exists(Exp* loc);   // True if the given location (not subscripted) exists as a source
04601         Exp*        localise(Exp* e);   // Localise to this call if necessary
04602 };
04603 
04604 ArgSourceProvider::ArgSourceProvider(CallStatement* call) : call(call) {
04605     Proc* procDest = call->getDestProc();
04606     if (procDest && procDest->isLib()) {
04607         src = SRC_LIB;
04608         callSig = call->getSignature();
04609         n = callSig->getNumParams();
04610         i = 0;
04611     } else if (call->getCalleeReturn() != NULL) {
04612         src = SRC_CALLEE;
04613         calleeParams = &((UserProc*)procDest)->getParameters();
04614         pp = calleeParams->begin();
04615     } else {
04616         Signature* destSig = NULL;
04617         if (procDest)
04618             destSig = procDest->getSignature();
04619         if (destSig && destSig->isForced()) {
04620             src = SRC_LIB;
04621             callSig = destSig;
04622             n = callSig->getNumParams();
04623             i = 0;
04624         } else {
04625             src = SRC_COL;
04626             defCol = call->getDefCollector();
04627             cc = defCol->begin();
04628         }
04629     }
04630 }
04631 
04632 Exp* ArgSourceProvider::nextArgLoc() {
04633     Exp* s;
04634     bool allZero;
04635     switch(src) {
04636         case SRC_LIB:
04637             if (i == n) return NULL;
04638             s = callSig->getParamExp(i++)->clone();
04639             s->removeSubscripts(allZero);       // e.g. m[sp{-} + 4] -> m[sp + 4]
04640             call->localiseComp(s);
04641             return s;
04642         case SRC_CALLEE:
04643             if (pp == calleeParams->end()) return NULL;
04644             s = ((Assignment*)*pp++)->getLeft()->clone();
04645             s->removeSubscripts(allZero);
04646             call->localiseComp(s);                  // Localise the components. Has the effect of translating into
04647                                                     // the contect of this caller 
04648             return s;
04649         case SRC_COL:
04650             if (cc == defCol->end()) return NULL;
04651             // Give the location, i.e. the left hand side of the assignment
04652             return ((Assign*)*cc++)->getLeft();
04653     }
04654     return NULL;        // Suppress warning
04655 }
04656 
04657 Exp* ArgSourceProvider::localise(Exp* e) {
04658     if (src == SRC_COL) {
04659         // Provide the RHS of the current assignment
04660         Exp* ret = ((Assign*)*--cc)->getRight();
04661         ++cc;
04662         return ret;
04663     }
04664     // Else just use the call to localise
04665     return call->localiseExp(e);
04666 }
04667 
04668 Type* ArgSourceProvider::curType(Exp* e) {
04669     switch(src) {
04670         case SRC_LIB:
04671             return callSig->getParamType(i-1);
04672         case SRC_CALLEE: {
04673             Type* ty = ((Assignment*)*--pp)->getType();
04674             pp++;
04675             return ty;
04676         }
04677         case SRC_COL: {
04678             // Mostly, there won't be a type here, I would think...
04679             Type* ty = (*--cc)->getType();
04680             ++cc;
04681             return ty;
04682         }
04683     }
04684     return NULL;        // Suppress warning
04685 }
04686 
04687 bool ArgSourceProvider::exists(Exp* e) {
04688     bool allZero;
04689     switch (src) {
04690         case SRC_LIB:
04691             if (callSig->hasEllipsis())
04692                 // FIXME: for now, just don't check
04693                 return true;
04694             for (i=0; i < n; i++) {
04695                 Exp* sigParam = callSig->getParamExp(i)->clone();
04696                 sigParam->removeSubscripts(allZero);
04697                 call->localiseComp(sigParam);
04698                 if (*sigParam == *e)
04699                     return true;
04700             }
04701             return false;
04702         case SRC_CALLEE:
04703             for (pp = calleeParams->begin(); pp != calleeParams->end(); ++pp) {
04704                 Exp* par = ((Assignment*)*pp)->getLeft()->clone();
04705                 par->removeSubscripts(allZero);
04706                 call->localiseComp(par);
04707                 if (*par == *e)
04708                     return true;
04709             }
04710             return false;
04711         case SRC_COL:
04712             return defCol->existsOnLeft(e);
04713     }
04714     return false;           // Suppress warning
04715 }
04716 
04717 void CallStatement::updateArguments() {
04718     /* If this is a library call, source = signature
04719         else if there is a callee return, source = callee parameters
04720         else
04721           if a forced callee signature, source = signature
04722           else source is def collector in this call.
04723         oldArguments = arguments
04724         clear arguments
04725         for each arg lhs in source
04726             if exists in oldArguments, leave alone
04727             else if not filtered append assignment lhs=lhs to oldarguments
04728         for each argument as in oldArguments in reverse order
04729             lhs = as->getLeft
04730             if (lhs does not exist in source) continue
04731             if filterParams(lhs) continue
04732             insert as into arguments, considering sig->argumentCompare
04733     */
04734     // Note that if propagations are limited, arguments and collected reaching definitions can be in terms of phi
04735     // statements that have since been translated to assignments. So propagate through them now
04736     // FIXME: reconsider! There are problems (e.g. with test/pentium/fromSSA2, test/pentium/fbranch) if you propagate
04737     // to the expressions in the arguments (e.g. m[esp{phi1}-20]) but don't propagate into ordinary statements that
04738     // define the actual argument. For example, you might have m[esp{-}-56] in the call, but the actual definition of
04739     // the printf argument is still m[esp{phi1} -20] = "%d".
04740     if (EXPERIMENTAL) {
04741         bool convert;
04742         proc->propagateStatements(convert, 88);
04743     }
04744     StatementList oldArguments(arguments);
04745     arguments.clear();
04746     if (EXPERIMENTAL) {
04747         // I don't really know why this is needed, but I was seeing r28 := ((((((r28{-}-4)-4)-4)-8)-4)-4)-4:
04748         DefCollector::iterator dd;
04749         for (dd = defCol.begin(); dd != defCol.end(); ++dd)
04750             (*dd)->simplify();
04751     }
04752 
04753     Signature* sig = proc->getSignature();
04754     // Ensure everything in the callee's signature (if this is a library call), or the callee parameters (if available),
04755     // or the def collector if not,  exists in oldArguments
04756     ArgSourceProvider asp(this);
04757     Exp* loc;
04758     while ((loc = asp.nextArgLoc()) != NULL) {
04759         if (proc->filterParams(loc))
04760             continue;
04761         if (!oldArguments.existsOnLeft(loc)) {
04762             // Check if the location is renamable. If not, localising won't work, since it relies on definitions
04763             // collected in the call, and you just get m[...]{-} even if there are definitions.
04764             Exp* rhs;
04765             if (proc->canRename(loc))
04766                 rhs = asp.localise(loc->clone());
04767             else
04768                 rhs = loc->clone();
04769             Type* ty = asp.curType(loc);
04770             Assign* as = new Assign(ty, loc->clone(), rhs);
04771             as->setNumber(number);          // Give the assign the same statement number as the call (for now)
04772             as->setParent(this);
04773             as->setProc(proc);
04774             as->setBB(pbb);
04775             oldArguments.append(as);
04776         }
04777     }
04778 
04779     StatementList::iterator it;
04780     for (it = oldArguments.end(); it != oldArguments.begin(); ) {
04781         --it;                                       // Becuase we are using a forwards iterator backwards
04782         // Make sure the LHS is still in the callee signature / callee parameters / use collector
04783         Assign* as = (Assign*)*it;
04784         Exp* lhs = as->getLeft();
04785         if (!asp.exists(lhs)) continue;
04786         if (proc->filterParams(lhs))
04787             continue;                       // Filtered out: delete it
04788 
04789         // Insert as, in order, into the existing set of definitions
04790         StatementList::iterator nn;
04791         bool inserted = false;
04792         for (nn = arguments.begin(); nn != arguments.end(); ++nn) {
04793             if (sig->argumentCompare(*as, *(Assign*)*nn)) {     // If the new assignment is less than the current one
04794                 nn = arguments.insert(nn, as);                  // then insert before this position
04795                 inserted = true;
04796                 break;
04797             }
04798         }
04799         if (!inserted)
04800             arguments.insert(arguments.end(), as);              // In case larger than all existing elements
04801     }
04802 
04803 }
04804 
04805 // Calculate results(this) = defines(this) isect live(this)
04806 // Note: could use a LocationList for this, but then there is nowhere to store the types (for DFA based TA)
04807 // So the RHS is just ignored
04808 StatementList* CallStatement::calcResults() {
04809     StatementList* ret = new StatementList;
04810     if (procDest) {
04811         Signature* sig = procDest->getSignature();
04812         if (procDest && procDest->isLib()) {
04813             int n = sig->getNumReturns();
04814             for (int i=1; i < n; i++) {                     // Ignore first (stack pointer) return
04815                 Exp* sigReturn = sig->getReturnExp(i);
04816 #if SYMS_IN_BACK_END
04817                 // But we have translated out of SSA form, so some registers have had to have been replaced with locals
04818                 // So wrap the return register in a ref to this and check the locals
04819                 RefExp* wrappedRet = new RefExp(sigReturn, this);
04820                 char* locName = proc->findLocal(wrappedRet);    // E.g. r24{16}
04821                 if (locName)
04822                     sigReturn = Location::local(locName, proc); // Replace e.g. r24 with local19
04823 #endif
04824                 if (useCol.exists(sigReturn)) {
04825                     ImplicitAssign* as = new ImplicitAssign(getTypeFor(sigReturn), sigReturn);
04826                     ret->append(as);
04827                 }
04828             }
04829         } else {
04830             Exp* rsp = Location::regOf(proc->getSignature()->getStackRegister(proc->getProg()));
04831             StatementList::iterator dd;
04832             for (dd = defines.begin(); dd != defines.end(); ++dd) {
04833                 Exp* lhs = ((Assign*)*dd)->getLeft();
04834                 // The stack pointer is allowed as a define, so remove it here as a special case non result
04835                 if (*lhs == *rsp) continue;
04836                 if (useCol.exists(lhs))
04837                     ret->append(*dd);
04838             }
04839         }
04840     } else {
04841         // For a call with no destination at this late stage, use everything live at the call except for the stack
04842         // pointer register. Needs to be sorted
04843         UseCollector::iterator rr;                              // Iterates through reaching definitions
04844         StatementList::iterator nn;                             // Iterates through new results
04845         Signature* sig = proc->getSignature();
04846         int sp = sig->getStackRegister();
04847         for (rr = useCol.begin(); rr != useCol.end(); ++rr) {
04848             Exp* loc = *rr;
04849             if (proc->filterReturns(loc)) continue;             // Ignore filtered locations
04850             if (loc->isRegN(sp)) continue;                      // Ignore the stack pointer
04851             ImplicitAssign* as = new ImplicitAssign(loc);       // Create an implicit assignment
04852             bool inserted = false;
04853             for (nn = ret->begin(); nn != ret->end(); ++nn) {
04854                 // If the new assignment is less than the current one,
04855                 if (sig->returnCompare(*as, *(Assignment*)*nn)) {
04856                     nn = ret->insert(nn, as);                   // then insert before this position
04857                     inserted = true;
04858                     break;
04859                 }
04860             }
04861             if (!inserted)
04862                 ret->insert(ret->end(), as);                    // In case larger than all existing elements
04863         }
04864     }
04865     return ret;
04866 }
04867 
04868 #if 0
04869 void TypingStatement::setType(Type* ty) {
04870     type = ty;
04871 }
04872 #endif
04873 
04874 void CallStatement::removeDefine(Exp* e) {
04875     StatementList::iterator ss;
04876     for (ss = defines.begin(); ss != defines.end(); ++ss) {
04877         Assign* as = ((Assign*)*ss);
04878         if (*as->getLeft() == *e) {
04879             defines.erase(ss);
04880             return;
04881         }
04882     }
04883     LOG << "WARNING: could not remove define " << e << " from call " << this << "\n";
04884 }
04885 
04886 bool CallStatement::isChildless() {
04887     if (procDest == NULL) return true;
04888     if (procDest->isLib()) return false;
04889     // Early in the decompile process, recursive calls are treated as childless, so they use and define all
04890     if (((UserProc*)procDest)->isEarlyRecursive())
04891         return true;
04892     return calleeReturn == NULL;
04893 }
04894 
04895 Exp* CallStatement::bypassRef(RefExp* r, bool& ch) {
04896     Exp* base = r->getSubExp1();
04897     Exp* proven;
04898     ch = false;
04899     if (procDest && procDest->isLib()) {
04900         Signature* sig = procDest->getSignature();
04901         proven = sig->getProven(base);  
04902         if (proven == NULL) {           // Not (known to be) preserved
04903             if (sig->findReturn(base) != -1)
04904                 return r;               // Definately defined, it's the return
04905             // Otherwise, not all that sure. Assume that library calls pass things like local variables
04906         }
04907     } else {
04908         // Was using the defines to decide if something is preserved, but consider sp+4 for stack based machines
04909         // Have to use the proven information for the callee (if any)
04910         if (procDest == NULL)
04911             return r;               // Childless callees transmit nothing
04912         //if (procDest->isLocal(base))                  // ICK! Need to prove locals and parameters through calls...
04913         // FIXME: temporary HACK! Ignores alias issues.
04914         if (!procDest->isLib() && ((UserProc*)procDest)->isLocalOrParamPattern(base)) {
04915             Exp* ret = localiseExp(base->clone());  // Assume that it is proved as preserved
04916             ch = true;
04917             if (VERBOSE)
04918                 LOG << base << " allowed to bypass call statement " << number << " ignoring aliasing; result " << ret <<
04919                     "\n";
04920             return ret;
04921         }
04922             
04923         proven = procDest->getProven(base);         // e.g. r28+4
04924     }
04925     if (proven == NULL)
04926         return r;                                       // Can't bypass, since nothing proven
04927     Exp* to = localiseExp(base);                        // e.g. r28{17}
04928     assert(to);
04929     proven = proven->clone();                           // Don't modify the expressions in destProc->proven!
04930     proven = proven->searchReplaceAll(base, to, ch);    // e.g. r28{17} + 4
04931     if (ch && VERBOSE)
04932         LOG << "bypassRef() replacing " << r << " with " << proven << "\n";
04933     return proven;
04934 }
04935 
04936 void ReturnStatement::removeModified(Exp* loc) {
04937     modifieds.removeDefOf(loc);
04938     returns.removeDefOf(loc);
04939 }
04940 
04941 void CallStatement::addDefine(ImplicitAssign* as) {
04942     defines.append(as);
04943 }
04944 
04945 TypingStatement::TypingStatement(Type* ty) : type(ty) {
04946 }
04947 
04948 // NOTE: ImpRefStatement not yet used
04949 void ImpRefStatement::print(std::ostream& os, bool html) {
04950     os << "     *";             // No statement number
04951     if (html) {
04952         os << "</td><td>";
04953         os << "<a name=\"stmt" << std::dec << number << "\">";
04954     }
04955     os << type << "* IMP REF " << addressExp;
04956     if (html)
04957         os << "</a></td>";
04958 }
04959 
04960 void ImpRefStatement::meetWith(Type* ty, bool& ch) {
04961     type = type->meetWith(ty, ch);
04962 }
04963 
04964 Statement* ImpRefStatement::clone() {
04965     return new ImpRefStatement(type->clone(), addressExp->clone());
04966 }
04967 bool ImpRefStatement::accept(StmtVisitor* visitor) {
04968     return visitor->visit(this);
04969 }
04970 bool    ImpRefStatement::accept(StmtExpVisitor* v) {
04971     bool override;
04972     bool ret = v->visit(this, override);
04973     if (override)
04974         return ret;
04975     if (ret) ret = addressExp->accept(v->ev);
04976     return ret;
04977 }
04978 bool    ImpRefStatement::accept(StmtModifier* v) {
04979     bool recur;
04980     v->visit(this, recur);
04981     v->mod->clearMod();
04982     if (recur) addressExp = addressExp->accept(v->mod);
04983     if (VERBOSE && v->mod->isMod())
04984         LOG << "ImplicitRef changed: now " << this << "\n";
04985     return true;
04986 }
04987 bool    ImpRefStatement::accept(StmtPartModifier* v) {
04988     bool recur;
04989     v->visit(this, recur);
04990     v->mod->clearMod();
04991     if (recur) addressExp = addressExp->accept(v->mod);
04992     if (VERBOSE && v->mod->isMod())
04993         LOG << "ImplicitRef changed: now " << this << "\n";
04994     return true;
04995 }
04996 bool    ImpRefStatement::search(Exp* search, Exp*& result) {
04997     result = NULL;
04998     return addressExp->search(search, result);
04999 }
05000 bool    ImpRefStatement::searchAll(Exp* search, std::list<Exp*, std::allocator<Exp*> >& result) {
05001     return addressExp->searchAll(search, result);
05002 }
05003 bool    ImpRefStatement::searchAndReplace(Exp* search, Exp* replace, bool cc) {
05004     bool change;
05005     addressExp = addressExp->searchReplaceAll(search, replace, change);
05006     return change;
05007 }
05008 void    ImpRefStatement::simplify() {addressExp = addressExp->simplify();}
05009 
05010 void CallStatement::eliminateDuplicateArgs() {
05011     StatementList::iterator it;
05012     LocationSet ls;
05013     for (it = arguments.begin(); it != arguments.end(); ) {
05014         Exp* lhs = ((Assignment*)*it)->getLeft();
05015         if (ls.exists(lhs)) {
05016             // This is a duplicate
05017             it = arguments.erase(it);
05018             continue;
05019         }
05020         ls.insert(lhs);
05021         ++it;
05022     }
05023 }
05024 
05025 void PhiAssign::enumerateParams(std::list<Exp*>& le) {
05026     iterator it;
05027     for (it = begin(); it != end(); ++it) {
05028         if (it->e == NULL) continue;
05029         RefExp* r = new RefExp(it->e, it->def);
05030         le.push_back(r);
05031     }
05032 }
05033 
05034 // For debugging
05035 void dumpDestCounts(std::map<Exp*, int, lessExpStar>* destCounts) {
05036     std::map<Exp*, int, lessExpStar>::iterator it;
05037     for (it = destCounts->begin(); it != destCounts->end(); ++it) {
05038         std::cerr << std::setw(4) << std::dec << it->second << " " << it->first << "\n";
05039     }
05040 }
05041 
05042 bool JunctionStatement::accept(StmtVisitor* visitor)
05043 {
05044     return true;
05045 }
05046 
05047 bool JunctionStatement::accept(StmtExpVisitor* visitor)
05048 {
05049     return true;
05050 }
05051 
05052 bool JunctionStatement::accept(StmtModifier* visitor)
05053 {
05054     return true;
05055 }
05056 
05057 bool JunctionStatement::accept(StmtPartModifier* visitor)
05058 {
05059     return true;
05060 }
05061 
05062 void JunctionStatement::print(std::ostream &os, bool html)
05063 {
05064     os << std::setw(4) << std::dec << number << " ";
05065     if (html) {
05066         os << "</td><td>";
05067         os << "<a name=\"stmt" << std::dec << number << "\">";
05068     }
05069     os << "JUNCTION ";
05070     for (int i = 0; i < pbb->getNumInEdges(); i++) {
05071         os << std::hex << pbb->getInEdges()[i]->getHiAddr() << std::dec;
05072         if (pbb->isBackEdge(i))
05073             os << "*";
05074         os << " ";
05075     }
05076     if (isLoopJunction())
05077         os << "LOOP";
05078     os << "\n\t\t\tranges: ";
05079     ranges.print(os);
05080     if (html)
05081         os << "</a></td>";
05082 }
05083 
05084 // Map registers and temporaries to locals
05085 void Statement::mapRegistersToLocals() {
05086     ExpRegMapper erm(proc);
05087     StmtRegMapper srm(&erm);
05088     accept(&srm);
05089 }
05090 
05091 void Statement::insertCasts() {
05092     // First we postvisit expressions using a StmtModifier and an ExpCastInserter
05093     ExpCastInserter eci(proc);
05094     StmtModifier sm(&eci, true);        // True to ignore collectors
05095     accept(&sm);
05096     // Now handle the LHS of assigns that happen to be m[...], using a StmtCastInserter
05097     StmtCastInserter sci;
05098     accept(&sci);
05099 }
05100 
05101 void Statement::replaceSubscriptsWithLocals() {
05102     ExpSsaXformer esx(proc);
05103     StmtSsaXformer ssx(&esx, proc);
05104     accept(&ssx);
05105 }
05106 
05107 void Statement::dfaMapLocals() {
05108     DfaLocalMapper dlm(proc);
05109     StmtModifier sm(&dlm, true);        // True to ignore def collector in return statement
05110     accept(&sm);
05111     if (VERBOSE && dlm.change)
05112         LOG << "statement mapped with new local(s): " << number << "\n";
05113 }
05114 
05115 void CallStatement::setNumber(int num) {
05116     number = num;
05117     // Also number any existing arguments. Important for library procedures, since these have arguments set by the front
05118     // end based in their signature
05119     StatementList::iterator aa;
05120     for (aa = arguments.begin(); aa != arguments.end(); ++aa)
05121         (*aa)->setNumber(num);
05122 }

Generated on Tue Sep 19 21:18:34 2006 for Boomerang by  doxygen 1.4.6