rtl.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 1998-2001, The University of Queensland
00003  * Copyright (C) 2000-2001, Sun Microsystems, Inc
00004  * Copyright (C) 2002, Trent Waddington
00005  *
00006  * See the file "LICENSE.TERMS" for information on usage and
00007  * redistribution of this file, and for a DISCLAIMER OF ALL
00008  * WARRANTIES.
00009  *
00010  */
00011 
00012 /*==============================================================================
00013  * FILE:       rtl.cc
00014  * OVERVIEW:   Implementation of the classes that describe a low level RTL (
00015  *             register transfer list)
00016  *============================================================================*/
00017 
00018 /*
00019  * $Revision: 1.38 $    // 1.33.2.3
00020  * 
00021  * 08 Apr 02 - Mike: Changes for boomerang
00022  * 13 May 02 - Mike: expList is no longer a pointer
00023  * 15 May 02 - Mike: Fixed a nasty bug in updateExp (when update with same
00024  *              expression as existing)
00025  * 25 Jul 02 - Mike: RTL is now list of Statements
00026  */
00027 
00028 #include <assert.h>
00029 #if defined(_MSC_VER) && _MSC_VER <= 1200
00030 #pragma warning(disable:4786)
00031 #endif 
00032 
00033 #include <iomanip>          // For setfill
00034 #include <sstream>
00035 #include "types.h"
00036 #include "statement.h"
00037 #include "exp.h"
00038 #include "type.h"
00039 #include "register.h"
00040 #include "cfg.h"
00041 #include "proc.h"           // For printing proc names
00042 #include "rtl.h"
00043 #include "prog.h"
00044 #include "hllcode.h"
00045 #include "util.h"
00046 #include "boomerang.h"
00047 #include "visitor.h"
00048 #include "log.h"
00049 // For some reason, MSVC 5.00 complains about use of undefined types a lot
00050 #if defined(_MSC_VER) && _MSC_VER <= 1100
00051 #include "signature.h"      // For MSVC 5.00
00052 #endif
00053 
00054 /******************************************************************************
00055  * RTL methods.
00056  * Class RTL represents low-level register transfer lists. 
00057  *****************************************************************************/
00058 
00059 /*==============================================================================
00060  * FUNCTION:        RTL::RTL
00061  * OVERVIEW:        Constructor.
00062  * PARAMETERS:      <none>
00063  * RETURNS:         N/a
00064  *============================================================================*/
00065 RTL::RTL()
00066   : nativeAddr(0)
00067 { }
00068 
00069 /*==============================================================================
00070  * FUNCTION:        RTL::RTL
00071  * OVERVIEW:        Constructor.
00072  * PARAMETERS:      instNativeAddr - the native address of the instruction
00073  *                  listExp - ptr to existing list of Exps
00074  * RETURNS:         N/a
00075  *============================================================================*/
00076 RTL::RTL(ADDRESS instNativeAddr, std::list<Statement*>* listStmt /*= NULL*/)
00077     : nativeAddr(instNativeAddr) {
00078     if (listStmt)
00079         stmtList = *listStmt;
00080 }
00081 
00082 /*==============================================================================
00083  * FUNCTION:        RTL::RTL
00084  * OVERVIEW:        Copy constructor. A deep clone is made of the given object
00085  *                  so that the lists of Exps do not share memory.
00086  * PARAMETERS:      other: RTL to copy from
00087  * RETURNS:         N/a
00088  *============================================================================*/
00089 RTL::RTL(const RTL& other) : nativeAddr(other.nativeAddr) {
00090     std::list<Statement*>::const_iterator it;
00091     for (it = other.stmtList.begin(); it != other.stmtList.end(); it++) {
00092         stmtList.push_back((*it)->clone());
00093     }
00094 }
00095 
00096 /*==============================================================================
00097  * FUNCTION:        RTL::~RTL
00098  * OVERVIEW:        Destructor.
00099  * PARAMETERS:      <none>
00100  * RETURNS:         N/a
00101  *============================================================================*/
00102 RTL::~RTL() { }
00103 
00104 /*==============================================================================
00105  * FUNCTION:        RTL::operator=
00106  * OVERVIEW:        Assignment copy (deep).
00107  * PARAMETERS:      other - RTL to copy
00108  * RETURNS:         a reference to this object
00109  *============================================================================*/
00110 RTL& RTL::operator=(RTL& other) {
00111     if (this != &other) {
00112         // Do a deep copy always
00113         iterator it;
00114         for (it = other.stmtList.begin(); it != other.stmtList.end(); it++)
00115             stmtList.push_back((*it)->clone());
00116         
00117         nativeAddr = other.nativeAddr;
00118     }
00119     return *this;
00120 }
00121 
00122 /*==============================================================================
00123  * FUNCTION:        RTL:clone
00124  * OVERVIEW:        Deep copy clone; deleting the clone will not affect this
00125  *                   RTL object
00126  * PARAMETERS:      <none>
00127  * RETURNS:         Pointer to a new RTL that is a clone of this one
00128  *============================================================================*/
00129 RTL* RTL::clone() {
00130     std::list<Statement*> le;
00131     iterator it;
00132 
00133     for (it = stmtList.begin(); it != stmtList.end(); it++) {
00134         le.push_back((*it)->clone());
00135     }
00136     
00137     RTL* ret = new RTL(nativeAddr, &le);
00138     return ret;
00139 }
00140 
00141 // visit this RTL, and all its Statements
00142 bool RTL::accept(StmtVisitor* visitor) {
00143     // Might want to do something at the RTL level:
00144     if (!visitor->visit(this)) return false;
00145     iterator it;
00146     for (it = stmtList.begin(); it != stmtList.end(); it++) {
00147         if (! (*it)->accept(visitor)) return false;
00148     }
00149     return true;
00150 }
00151 
00152 /*==============================================================================
00153  * FUNCTION:        RTL::deepCopyList
00154  * OVERVIEW:        Make a copy of this RTLs list of Exp* to the given list
00155  * PARAMETERS:      Ref to empty list to copy to
00156  * RETURNS:         Nothing
00157  *============================================================================*/
00158 void RTL::deepCopyList(std::list<Statement*>& dest) {
00159     std::list<Statement*>::iterator it;
00160 
00161     for (it = stmtList.begin(); it != stmtList.end(); it++) {
00162         dest.push_back((*it)->clone());
00163     }
00164 }
00165 
00166 /*==============================================================================
00167  * FUNCTION:        RTL::appendStmt
00168  * OVERVIEW:        Append the given Statement at the end of this RTL
00169  * NOTE:            Exception: Leaves any flag call at the end (so may push exp
00170  *                   to second last position, instead of last)
00171  * NOTE:            stmt is NOT copied. This is different to how UQBT was!
00172  * PARAMETERS:      s: pointer to Statement to append
00173  * RETURNS:         Nothing
00174  *============================================================================*/
00175 void RTL::appendStmt(Statement* s) {
00176     if (stmtList.size()) {
00177         if (stmtList.back()->isFlagAssgn()) {
00178             iterator it = stmtList.end();
00179             stmtList.insert(--it, s);
00180             return;
00181         }
00182     }
00183     stmtList.push_back(s);
00184 }
00185 
00186 /*==============================================================================
00187  * FUNCTION:        RTL::prependStmt
00188  * OVERVIEW:        Prepend the given Statement at the start of this RTL
00189  * NOTE:            No clone of the statement is made. This is different to how UQBT was
00190  * PARAMETERS:      s: Ptr to Statement to prepend
00191  * RETURNS:         Nothing
00192  *============================================================================*/
00193 void RTL::prependStmt(Statement* s) {
00194     stmtList.push_front(s);
00195 }
00196 
00197 /*==============================================================================
00198  * FUNCTION:        RTL::appendListStmt
00199  * OVERVIEW:        Append a given list of Statements to this RTL
00200  * NOTE:            A copy of the Statements in le are appended
00201  * PARAMETERS:      rtl: list of Exps to insert
00202  * RETURNS:         Nothing
00203  *============================================================================*/
00204 void RTL::appendListStmt(std::list<Statement*>& le) {
00205     iterator it;
00206     for (it = le.begin();  it != le.end();  it++) {
00207         stmtList.insert(stmtList.end(), (*it)->clone());
00208     }
00209 }
00210 
00211 /*==============================================================================
00212  * FUNCTION:        RTL::appendRTL
00213  * OVERVIEW:        Append the Statemens of another RTL to this object
00214  * NOTE:            A copy of the Statements in r are appended
00215  * PARAMETERS:      r: reterence to RTL whose Exps we are to insert
00216  * RETURNS:         Nothing
00217  *============================================================================*/
00218 void RTL::appendRTL(RTL& r) {
00219     appendListStmt(r.stmtList);
00220 }
00221 
00222 /*==============================================================================
00223  * FUNCTION:        RTL::insertStmt
00224  * OVERVIEW:        Insert the given Statement before index i
00225  * NOTE:            No copy of stmt is made. This is different to UQBT
00226  * PARAMETERS:      s: pointer to the Statement to insert
00227  *                  i: position to insert before (0 = first)
00228  * RETURNS:         Nothing
00229  *============================================================================*/
00230 void RTL::insertStmt(Statement* s, unsigned i) {
00231     // Check that position i is not out of bounds
00232     assert (i < stmtList.size() || stmtList.size() == 0);
00233 
00234     // Find the position
00235     iterator pp = stmtList.begin();
00236     for (; i > 0; i--, pp++);
00237 
00238     // Do the insertion
00239     stmtList.insert(pp, s);
00240 }
00241 
00242 void RTL::insertStmt(Statement* s, iterator it) {
00243     stmtList.insert(it, s);
00244 }
00245 
00246 /*==============================================================================
00247  * FUNCTION:        RTL::updateStmt
00248  * OVERVIEW:        Replace the ith Statement with the given one
00249  * PARAMETERS:      s: pointer to the new Exp
00250  *                  i: index of Exp position (0 = first)
00251  * RETURNS:         Nothing
00252  *============================================================================*/
00253 void RTL::updateStmt(Statement *s, unsigned i) {
00254     // Check that position i is not out of bounds
00255     assert (i < stmtList.size());
00256 
00257     // Find the position
00258     iterator pp = stmtList.begin();
00259     for (; i > 0; i--, pp++);    
00260 
00261     // Note that sometimes we might update even when we don't know if it's
00262     // needed, e.g. after a searchReplace.
00263     // In that case, don't update, and especially don't delete the existing
00264     // statement (because it's also the one we are updating!)
00265     if (*pp != s) {
00266         // Do the update
00267         if (*pp) ;//delete *pp;
00268         *pp = s;
00269     }
00270 }
00271 
00272 void RTL::deleteStmt(unsigned i) {
00273     // check that position i is not out of bounds
00274     assert (i < stmtList.size());
00275 
00276     // find the position
00277     iterator pp = stmtList.begin();
00278     for (; i > 0; i--, pp++);    
00279 
00280     // do the delete
00281     stmtList.erase(pp);
00282 }
00283 
00284 void RTL::deleteLastStmt() {
00285     assert(stmtList.size());
00286     stmtList.erase(--stmtList.end());
00287 }
00288 
00289 void RTL::replaceLastStmt(Statement* repl) {
00290     assert(stmtList.size());
00291     Statement*& last = stmtList.back();
00292     last = repl;
00293 }
00294 
00295     
00296 /*==============================================================================
00297  * FUNCTION:        RTL::getNumStmt
00298  * OVERVIEW:        Get the number of Statements in this RTL
00299  * PARAMETERS:      None
00300  * RETURNS:         Integer number of Statements
00301  *============================================================================*/
00302 int RTL::getNumStmt() {
00303     return stmtList.size();
00304 }
00305 
00306 /*==============================================================================
00307  * FUNCTION:        RTL::at
00308  * OVERVIEW:        Provides indexing on a list. Changed from operator[] so that
00309  *                  we keep in mind it is linear in its execution time.
00310  * PARAMETERS:      i - the index of the element we want (0 = first)
00311  * RETURNS:         the element at the given index or NULL if the index is out
00312  *                  of bounds
00313  *============================================================================*/
00314 Statement* RTL::elementAt(unsigned i) {
00315     iterator it;
00316     for (it = stmtList.begin();  i > 0 && it != stmtList.end();  i--, it++);
00317     if (it == stmtList.end()) {
00318         return NULL;
00319     }
00320     return *it;
00321 }
00322 
00323 /*==============================================================================
00324  * FUNCTION:        RTL::print
00325  * OVERVIEW:        Prints this object to a stream in text form.
00326  * PARAMETERS:      os - stream to output to (often cout or cerr)
00327  * RETURNS:         <nothing>
00328  *============================================================================*/
00329 void RTL::print(std::ostream& os /*= cout*/, bool html /*=false*/) {
00330 
00331     if (html)
00332         os << "<tr><td>";
00333     // print out the instruction address of this RTL
00334     os << std::hex << std::setfill('0') << std::setw(8) << nativeAddr;
00335     os << std::dec << std::setfill(' ');      // Ugh - why is this needed?
00336     if (html)
00337         os << "</td>";
00338 
00339     // Print the statements
00340     // First line has 8 extra chars as above
00341     bool bFirst = true;
00342     iterator ss;
00343     for (ss = stmtList.begin(); ss != stmtList.end(); ss++) {
00344         Statement* stmt = *ss;
00345         if (html) {
00346             if (!bFirst) os << "<tr><td></td>";
00347             os << "<td width=\"50\" align=\"center\">";
00348         } else {
00349             if (bFirst) os << " ";
00350             else        os << std::setw(9) << " ";
00351         }
00352         if (stmt) stmt->print(os, html);
00353         // Note: we only put newlines where needed. So none at the end of
00354         // Statement::print; one here to separate from other statements
00355         if (html)
00356             os << "</td></tr>";
00357         os << "\n";
00358         bFirst = false;
00359     }
00360     if (stmtList.empty()) os << std::endl;     // New line for NOP
00361 }
00362 
00363 void RTL::dump() {
00364     print(std::cerr);
00365 }
00366 
00367 extern char debug_buffer[];
00368 
00369 char* RTL::prints() {
00370       std::ostringstream ost;
00371       print(ost);
00372       strncpy(debug_buffer, ost.str().c_str(), DEBUG_BUFSIZE-1);
00373       debug_buffer[DEBUG_BUFSIZE-1] = '\0';
00374       return debug_buffer;
00375 }
00376 
00377 /*==============================================================================
00378  * FUNCTION:        operator<<
00379  * OVERVIEW:        Output operator for RTL*
00380  *                  Just makes it easier to use e.g. std::cerr << myRTLptr
00381  * PARAMETERS:      os: output stream to send to
00382  *                  p: ptr to RTL to print to the stream
00383  * RETURNS:         copy of os (for concatenation)
00384  *============================================================================*/
00385 std::ostream& operator<<(std::ostream& os, RTL* r) {
00386     if (r == NULL) {os << "NULL "; return os;}
00387     r->print(os);
00388     return os;
00389 }
00390 
00391 /*==============================================================================
00392  * FUNCTION:        RTL::updateAddress
00393  * OVERVIEW:        Set the nativeAddr field
00394  * PARAMETERS:      Native address
00395  * RETURNS:         Nothing
00396  *============================================================================*/
00397 void RTL::updateAddress(ADDRESS addr) {
00398     nativeAddr = addr;
00399 }
00400 
00401 /*==============================================================================
00402  * FUNCTION:        RTL::searchReplace
00403  * OVERVIEW:        Replace all instances of search with replace.
00404  * PARAMETERS:      search - ptr to an expression to search for
00405  *                  replace - ptr to the expression with which to replace it
00406  * RETURNS:         <nothing>
00407  *============================================================================*/
00408 bool RTL::searchAndReplace(Exp* search, Exp* replace) {
00409     bool ch = false;
00410     for (iterator it = stmtList.begin(); it != stmtList.end(); it++)
00411         ch |= (*it)->searchAndReplace(search, replace);
00412     return ch;
00413 }
00414 
00415 /*==============================================================================
00416  * FUNCTION:        RTL::searchAll
00417  * OVERVIEW:        Find all instances of the search expression
00418  * PARAMETERS:      search - a location to search for
00419  *                  result - a list which will have any matching exprs
00420  *                           appended to it
00421  * RETURNS:         true if there were any matches
00422  *============================================================================*/
00423 bool RTL::searchAll(Exp* search, std::list<Exp *> &result) {
00424     bool found = false;
00425     for (iterator it = stmtList.begin(); it != stmtList.end(); it++) {
00426         Statement *e = *it;
00427         Exp* res;
00428         if (e->search(search, res)) {
00429             found = true;
00430             result.push_back(res);
00431         }
00432     }
00433     return found;
00434 }
00435 
00436 /*==============================================================================
00437  * FUNCTION:        RTL::clear
00438  * OVERVIEW:        Clear the list of Exps
00439  * PARAMETERS:      None
00440  * RETURNS:         Nothing
00441  *============================================================================*/
00442 void RTL::clear() {
00443     stmtList.clear();
00444 }
00445 
00446 /*==============================================================================
00447  * FUNCTION:        RTL::insertAssign
00448  * OVERVIEW:        Prepends or appends an assignment to the front or back of
00449  *                    this RTL
00450  * NOTE:            Is this really used? What about types?
00451  * ASSUMES:         Assumes that pLhs and pRhs are "new" Exp's that are
00452  *                  not part of other Exps. (Otherwise, there will be problems
00453  *                  when deleting this Exp)
00454  *                  If size == -1, assumes there is already at least one assign-
00455  *                    ment in this RTL
00456  * PARAMETERS:      pLhs: ptr to Exp to place on LHS
00457  *                  pRhs: ptr to Exp to place on the RHS
00458  *                  prep: true if prepend (else append)
00459  *                  type: type of the transfer, or NULL
00460  * RETURNS:         <nothing>
00461  *============================================================================*/
00462 void RTL::insertAssign(Exp* pLhs, Exp* pRhs, bool prep,
00463                         Type* type /*= NULL */) {
00464     // Generate the assignment expression
00465     Assign* asgn = new Assign(type, pLhs, pRhs);
00466     if (prep)
00467         prependStmt(asgn);
00468     else
00469         appendStmt(asgn);
00470 }
00471 
00472 /*==============================================================================
00473  * FUNCTION:        RTL::insertAfterTemps
00474  * OVERVIEW:        Inserts an assignment at or near the top of this RTL, after
00475  *                    any assignments to temporaries. If the last assignment
00476  *                    is to a temp, the insertion is done before that last
00477  *                    assignment
00478  * ASSUMES:         Assumes that ssLhs and ssRhs are "new" Exp's that are
00479  *                  not part of other Exps. (Otherwise, there will be problems
00480  *                  when deleting this Exp)
00481  *                  If type == NULL, assumes there is already at least one
00482  *                    assignment in this RTL (?)
00483  * NOTE:            Hopefully this is only a temporary measure
00484  * PARAMETERS:      pLhs: ptr to Exp to place on LHS
00485  *                  pRhs: ptr to Exp to place on the RHS
00486  *                  size: size of the transfer, or -1 to be the same as the
00487  *                    first assign this RTL
00488  * RETURNS:         <nothing>
00489  *============================================================================*/
00490 void RTL::insertAfterTemps(Exp* pLhs, Exp* pRhs, Type* type  /* NULL */) {
00491     iterator it;
00492     // First skip all assignments with temps on LHS
00493     for (it = stmtList.begin(); it != stmtList.end(); it++) {
00494         Statement *s = *it;
00495         if (!s->isAssign())
00496             break;
00497         Exp* LHS = ((Assign*)s)->getLeft();
00498         if (LHS->isTemp())
00499             break;
00500     }
00501 
00502     // Now check if the next Stmt is an assignment
00503     if ((it == stmtList.end()) || !(*it)->isAssign()) {
00504         // There isn't an assignment following. Use the previous Exp to insert
00505         // before
00506         if (it != stmtList.begin())
00507             it--;
00508     }
00509 
00510     if (type == NULL)
00511         type = getType();
00512 
00513     // Generate the assignment expression
00514     Assign* asgn = new Assign(type, pLhs, pRhs);
00515 
00516     // Insert before "it"
00517     stmtList.insert(it, asgn);
00518 }
00519 
00520 /*==============================================================================
00521  * FUNCTION:        RTL::getType
00522  * OVERVIEW:        Get the "type" for this RTL. Just gets the type of
00523  *                    the first assignment Exp
00524  * NOTE:            The type of the first assign may not be the type that you
00525  *                    want!
00526  * PARAMETERS:      None
00527  * RETURNS:         A pointer to the type
00528  *============================================================================*/
00529 Type* RTL::getType() {
00530     iterator it;
00531     for (it = stmtList.begin(); it != stmtList.end(); it++) {
00532         Statement *e = *it;
00533         if (e->isAssign())
00534             return ((Assign*)e)->getType();
00535     }
00536     return new IntegerType();   //  Default to 32 bit integer if no assignments
00537 }
00538 
00539 /*==============================================================================
00540  * FUNCTION:      RTL::areFlagsAffected
00541  * OVERVIEW:      Return true if this RTL affects the condition codes
00542  * NOTE:          Assumes that if there is a flag call Exp, then it is the last
00543  * PARAMETERS:    None
00544  * RETURNS:       Boolean as above
00545  *============================================================================*/
00546 bool RTL::areFlagsAffected() {
00547     if (stmtList.size() == 0) return false;
00548     // Get an iterator to the last RT
00549     iterator it = stmtList.end();
00550     if (it == stmtList.begin())
00551         return false;           // Not expressions at all
00552     it--;                       // Will now point to the end of the list
00553     Statement *e = *it;
00554     // If it is a flag call, then the CCs are affected
00555     return e->isFlagAssgn();
00556 }
00557 
00558 void RTL::generateCode(HLLCode *hll, BasicBlock *pbb, int indLevel) {
00559     for (iterator it = stmtList.begin();
00560       it != stmtList.end(); it++) {
00561         (*it)->generateCode(hll, pbb, indLevel);
00562     }
00563 }
00564 
00565 void RTL::simplify() {
00566     for (iterator it = stmtList.begin(); it != stmtList.end(); /*it++*/) {
00567         Statement *s = *it;
00568         s->simplify();        
00569         if (s->isBranch()) {
00570             Exp *cond =  ((BranchStatement*)s)->getCondExpr();
00571             if (cond && cond->getOper() == opIntConst) {
00572                 if (((Const*)cond)->getInt() == 0) {
00573                     if (VERBOSE)
00574                         LOG << "removing branch with false condition at " << getAddress()  << " " << *it << "\n";
00575                     it = stmtList.erase(it);
00576                     continue;
00577                 } else {
00578                     if (VERBOSE)
00579                         LOG << "replacing branch with true condition with goto at " << getAddress() << " " << *it <<
00580                             "\n";
00581                     *it = new GotoStatement(((BranchStatement*)s)->getFixedDest());
00582                 }
00583             }
00584         } else if (s->isAssign()) {
00585             Exp* guard = ((Assign*)s)->getGuard();
00586             if (guard && (guard->isFalse() || guard->isIntConst() && ((Const*)guard)->getInt() == 0)) {
00587                 // This assignment statement can be deleted
00588                 if (VERBOSE)
00589                     LOG << "removing assignment with false guard at " << getAddress() << " " << *it << "\n";
00590                 it = stmtList.erase(it);
00591                 continue;
00592             }
00593         }
00594         it++;
00595     }
00596 }
00597 
00598 /*==============================================================================
00599  * FUNCTION:        RTL::isCompare
00600  * OVERVIEW:        Return true if this is an unmodified compare instruction
00601  *                    of a register with an operand
00602  * NOTE:            Will also match a subtract if the flags are set
00603  * NOTE:            expOperand, if set, is not cloned
00604  * NOTE:            Assumes that the first subtract on the RHS is the actual
00605  *                    compare operation
00606  * PARAMETERS:      iReg: ref to integer to set with the register index
00607  *                  expOperand: ref to ptr to expression of operand
00608  * RETURNS:         True if found
00609  *============================================================================*/
00610 bool RTL::isCompare(int& iReg, Exp*& expOperand) {
00611     // Expect to see a subtract, then a setting of the flags
00612     // Dest of subtract should be a register (could be the always zero register)
00613     if (getNumStmt() < 2) return false;
00614     // Could be first some assignments to temporaries
00615     // But the actual compare could also be an assignment to a temporary
00616     // So we search for the first RHS with an opMinus, that has a LHS to
00617     // a register (whether a temporary or a machine register)
00618     int i=0;
00619     Exp* rhs;
00620     Statement* cur;
00621     do {
00622         cur = elementAt(i);
00623         if (cur->getKind() != STMT_ASSIGN) return false;
00624         rhs = ((Assign*)cur)->getRight();
00625         i++;
00626     } while (rhs->getOper() != opMinus && i < getNumStmt());
00627     if (rhs->getOper() != opMinus) return false;
00628     // We have a subtract assigning to a register.
00629     // Check if there is a subflags last
00630     Statement* last = elementAt(getNumStmt()-1);
00631     if (!last->isFlagAssgn()) return false;
00632     Exp* sub = ((Binary*)rhs)->getSubExp1();
00633     // Should be a compare of a register and something (probably a constant)
00634     if (!sub->isRegOf()) return false;
00635     // Set the register and operand expression, and return true
00636     iReg = ((Const*)((Unary*)sub)->getSubExp1())->getInt();
00637     expOperand = ((Binary*)rhs)->getSubExp2();
00638     return true;
00639 }
00640 
00641 bool RTL::isGoto() {
00642     if (stmtList.empty()) return false;
00643     Statement* last = stmtList.back();
00644     return last->getKind() == STMT_GOTO;
00645 }
00646 
00647 bool RTL::isBranch() {
00648     if (stmtList.empty()) return false;
00649     Statement* last = stmtList.back();
00650     return last->getKind() == STMT_BRANCH;
00651 }
00652 
00653 bool RTL::isCall() {
00654     if (stmtList.empty()) return false;
00655     Statement* last = stmtList.back();
00656     return last->getKind() == STMT_CALL;
00657 }
00658 
00659 // Use this slow function when you can't be sure that the HL Statement is last
00660 Statement* RTL::getHlStmt() {
00661     reverse_iterator rit;
00662     for (rit = stmtList.rbegin(); rit != stmtList.rend(); rit++) {
00663         if ((*rit)->getKind() != STMT_ASSIGN)
00664             return *rit;
00665     }
00666     return NULL;
00667 }
00668 
00669 int RTL::setConscripts(int n, bool bClear) {
00670     StmtConscriptSetter ssc(n, bClear);
00671     accept(&ssc);
00672     return ssc.getLast();
00673 }

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