00001 /* 00002 * Copyright (C) 2001, Sun Microsystems, Inc 00003 * Copyright (C) 2001, The University of Queensland 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.h 00014 * OVERVIEW: Definition of the classes that describe an RTL, a low-level 00015 * register transfer list. Higher-level RTLs (instance 00016 * of class HLJump, HLCall, etc.) represent information about 00017 * a control transfer instruction (CTI) in the source program. 00018 * analysis code adds information to existing higher-level 00019 * RTLs and sometimes creates new higher-level RTLs (e.g., for 00020 * switch statements). 00021 *============================================================================*/ 00022 00023 /* 00024 * $Revision: 1.55 $ // 1.51.2.1 00025 * 00026 * 08 Apr 02 - Mike: Mods for boomerang 00027 * 13 May 02 - Mike: expList is no longer a pointer 00028 * 25 Jul 03 - Mike: RTL now a list of Statements 00029 */ 00030 00031 #ifndef __RTL_H__ 00032 #define __RTL_H__ 00033 00034 #include <list> 00035 #include <vector> 00036 #include <map> 00037 #include <set> 00038 #include <iostream> 00039 #include "exp.h" 00040 #include "register.h" 00041 00042 class BasicBlock; 00043 class HLLCode; 00044 typedef BasicBlock* PBB; 00045 class Exp; 00046 class TypedExp; 00047 class DefSet; 00048 class UseSet; 00049 class Type; 00050 class Register; 00051 class Proc; 00052 class XMLProgParser; 00053 class StmtVisitor; 00054 00055 00056 /*============================================================================== 00057 * Class RTL: describes low level register transfer lists (actually lists of statements). 00058 * NOTE: when time permits, this class could be removed, replaced with new Statements that mark the current native 00059 * address 00060 *============================================================================*/ 00061 class RTL { 00062 ADDRESS nativeAddr; // RTL's source program instruction address 00063 std::list<Statement*> stmtList; // List of expressions in this RTL. 00064 public: 00065 RTL(); 00066 RTL(ADDRESS instNativeAddr, std::list<Statement*>* listStmt = NULL); 00067 RTL(const RTL& other); // Makes deep copy of "other" 00068 virtual ~RTL(); 00069 00070 typedef std::list<Statement*>::iterator iterator; 00071 typedef std::list<Statement*>::reverse_iterator reverse_iterator; 00072 00073 // Return a deep copy, including a deep copy of the list of Statements 00074 virtual RTL* clone(); 00075 00076 // Assignment copy: set this RTL to a deep copy of "other". 00077 RTL& operator=(RTL &other); 00078 00079 // Accept a visitor to this RTL 00080 virtual bool accept(StmtVisitor* visitor); 00081 00082 // Common enquiry methods 00083 ADDRESS getAddress() {return nativeAddr;} // Return RTL's native address 00084 void setAddress(ADDRESS a) {nativeAddr=a;} // Set the address 00085 Type* getType(); // Return type of first Assign. 00086 bool areFlagsAffected(); // True if flags are affected 00087 00088 // Statement list enquiry methods 00089 int getNumStmt(); // Return the number of Stmts in RTL. 00090 Statement* elementAt(unsigned i); // Return the i'th element in RTL. 00091 00092 // Statement list editing methods 00093 void appendStmt(Statement *s); // Add s to end of RTL. 00094 void prependStmt(Statement *s); // Add s to start of RTL. 00095 void insertStmt(Statement *s, unsigned i); // Insert s before expression at position i 00096 void insertStmt(Statement *s, iterator it); // Insert s before iterator it 00097 void updateStmt(Statement *s, unsigned i); // Change stmt at position i. 00098 void deleteStmt(unsigned int); // Delete expression at position i. 00099 void deleteLastStmt(); // Delete the last statement 00100 void replaceLastStmt(Statement* repl); // Replace the last Statement 00101 void clear(); // Remove all statements from this RTL. 00102 // Append list of exps to end. 00103 void appendListStmt(std::list<Statement*>& le); 00104 void appendRTL(RTL& rtl); // Append Statements from other RTL to end 00105 // Make a deep copy of the list of Exp* 00106 void deepCopyList(std::list<Statement*>& dest); 00107 // direct access to the list of expressions 00108 std::list<Statement*> &getList() { return stmtList; } 00109 00110 // Print RTL to a stream. 00111 virtual void print(std::ostream& os = std::cout, bool html = false); 00112 00113 void dump(); 00114 00115 // Set the RTL's source address 00116 void updateAddress(ADDRESS addr); 00117 00118 // Is this RTL a compare instruction? If so, the passed register and compared value (a semantic string) are set. 00119 bool isCompare(int& iReg, Exp*& pTerm); 00120 00121 // Return true if RTL loads the high half of an immediate constant into anything. If so, loads the already 00122 // shifted high value into the parameter. 00123 bool isHiImmedLoad(ADDRESS& uHiHalf); 00124 00125 // As above for low half. Extra parameters are required for SPARC, where bits are potentially transferred from 00126 // one register to another. 00127 bool isLoImmedLoad(ADDRESS& uLoHalf, bool& bTrans, int& iSrc); 00128 00129 // Do a machine dependent, and a standard simplification of the RTL. 00130 void allSimplify(); 00131 00132 // Perform forward substitutions of temps, if possible. Called from the above 00133 void forwardSubs(); 00134 00135 // Insert an assignment into this RTL 00136 // ssLhs: ptr to Exp to place on LHS 00137 // ssRhs: ptr to Exp to place on RHS 00138 // prep: true if prepend (else append) 00139 // type: type of the transfer, or NULL 00140 void insertAssign(Exp* ssLhs, Exp* ssRhs, bool prep, Type* type = NULL); 00141 00142 // Insert an assignment into this RTL, after temps have been defined 00143 // ssLhs: ptr to Exp to place on LHS 00144 // ssRhs: ptr to Exp to place on RHS 00145 // type: type of the transfer, or NULL 00146 void insertAfterTemps(Exp* ssLhs, Exp* ssRhs, Type* type = NULL); 00147 00148 // Replace all instances of "search" with "replace". 00149 virtual bool searchAndReplace(Exp* search, Exp* replace); 00150 00151 // Searches for all instances of "search" and adds them to "result" in reverse nesting order. The search is 00152 // optionally type sensitive. 00153 virtual bool searchAll(Exp* search, std::list<Exp*> &result); 00154 00155 // code generation 00156 virtual void generateCode(HLLCode *hll, BasicBlock *pbb, int indLevel); 00157 00158 // simplify all the uses/defs in this RTL 00159 virtual void simplify(); 00160 00161 // True if this RTL ends in a GotoStatement 00162 bool isGoto(); 00163 00164 // Is this RTL a call instruction? 00165 bool isCall(); 00166 00167 // Is this RTL a branch instruction? 00168 bool isBranch(); 00169 00170 // Get the "special" (High Level) Statement this RTL (else NULL) 00171 Statement* getHlStmt(); 00172 00173 // Print to a string (mainly for debugging) 00174 char* prints(); 00175 00176 // Set or clear all the "constant subscripts" (conscripts) in this RTL 00177 int setConscripts(int n, bool bClear); 00178 protected: 00179 00180 friend class XMLProgParser; 00181 }; 00182 00183 00184 00185 /*============================================================================== 00186 * The TableEntry class represents a single instruction - a string/RTL pair. 00187 * 00188 * This class plus ParamEntry and RTLInstDict should be moved to a separate 00189 * header file... 00190 *============================================================================*/ 00191 class TableEntry { 00192 public: 00193 TableEntry(); 00194 TableEntry(std::list<std::string>& p, RTL& rtl); 00195 00196 const TableEntry& operator=(const TableEntry& other); 00197 00198 void setParam(std::list<std::string>& p); 00199 void setRTL(RTL& rtl); 00200 00201 // non-zero return indicates failure 00202 int appendRTL(std::list<std::string>& p, RTL& rtl); 00203 00204 public: 00205 std::list<std::string> params; 00206 RTL rtl; 00207 00208 #define TEF_NEXTPC 1 00209 int flags; // aka required capabilities. Init. to 0 00210 }; 00211 00212 00213 /*============================================================================== 00214 * The ParamEntry class represents the details of a single parameter. 00215 *============================================================================*/ 00216 typedef enum {PARAM_SIMPLE, PARAM_ASGN, PARAM_LAMBDA, PARAM_VARIANT} ParamKind; 00217 00218 class ParamEntry { 00219 public: 00220 ParamEntry() { 00221 asgn = NULL; 00222 kind = PARAM_SIMPLE; 00223 type = NULL; 00224 regType = NULL; 00225 lhs = false; 00226 mark = 0; 00227 } 00228 ~ParamEntry() { 00229 if (type) delete type; 00230 if (regType) delete regType; 00231 } 00232 00233 std::list<std::string> params; /* PARAM_VARIANT & PARAM_ASGN only */ 00234 std::list<std::string> funcParams; /* PARAM_LAMBDA - late bound params */ 00235 Statement* asgn; /* PARAM_ASGN only */ 00236 bool lhs; /* True if this param ever appears on the LHS of an expression */ 00237 ParamKind kind; 00238 Type* type; 00239 Type* regType; /* Type of r[this], if any (void otherwise) */ 00240 std::set<int> regIdx; /* Values this param can take as an r[param] */ 00241 int mark; /* Traversal mark. (free temporary use, basically) */ 00242 }; 00243 00244 00245 /*============================================================================== 00246 * The RTLInstDict represents a dictionary that maps instruction names to the 00247 * parameters they take and a template for the Exp list describing their 00248 * semantics. It handles both the parsing of the SSL file that fills in 00249 * the dictionary entries as well as instantiation of an Exp list for a given 00250 * instruction name and list of actual parameters. 00251 *============================================================================*/ 00252 00253 class RTLInstDict { 00254 public: 00255 RTLInstDict(); 00256 ~RTLInstDict(); 00257 00258 // Parse a file containing a list of instructions definitions in SSL format and build the contents of this 00259 // dictionary. 00260 bool readSSLFile(const std::string& SSLFileName); 00261 00262 // Reset the object to "undo" a readSSLFile() 00263 void reset(); 00264 00265 // Return the signature of the given instruction. 00266 std::pair<std::string,unsigned> getSignature(const char* name); 00267 00268 // Appends an RTL to an idict entry, or Adds it to idict if an entry does not already exist. A non-zero return 00269 // indicates failure. 00270 int appendToDict(std::string &n, std::list<std::string>& p, RTL& rtl); 00271 00272 // Given an instruction name and list of actual parameters, return an instantiated RTL for the corresponding 00273 // instruction entry. 00274 std::list<Statement*>* instantiateRTL(std::string& name, ADDRESS natPC, std::vector<Exp*>& actuals); 00275 // As above, but takes an RTL & param list directly rather than doing a table lookup by name. 00276 std::list<Statement*>* instantiateRTL(RTL& rtls, ADDRESS natPC, std::list<std::string> ¶ms, 00277 std::vector<Exp*>& actuals); 00278 00279 // Transform the given list into another list which doesn't have post-variables, by either adding temporaries or 00280 // just removing them where possible. Modifies the list passed, and also returns a pointer to it. Second 00281 // parameter indicates whether the routine should attempt to optimize the resulting output, ie to minimize the 00282 // number of temporaries. This is recommended for fully expanded expressions (ie within uqbt), but unsafe 00283 // otherwise. 00284 std::list<Statement*>* transformPostVars(std::list<Statement*> *rts, bool optimise); 00285 00286 void print(std::ostream& os = std::cout); 00287 00288 // Add a new register to the machine 00289 void addRegister(const char *name, int id, int size, bool flt); 00290 00291 // If the top level operator of the given expression indicates any kind of type, update ty to match. 00292 bool partialType(Exp* exp, Type& ty); 00293 00294 // Go through the params and fixup any lambda functions 00295 void fixupParams(); 00296 00297 public: 00298 // A map from the symbolic representation of a register (e.g. "%g0") to its index within an array of registers. 00299 std::map<std::string, int, std::less<std::string> > RegMap; 00300 00301 // Similar to r_map but stores more info about a register such as its size, its addresss etc (see register.h). 00302 std::map<int, Register, std::less<int> > DetRegMap; 00303 00304 // A map from symbolic representation of a special (non-addressable) register to a Register object 00305 std::map<std::string, Register, std::less<std::string> > SpecialRegMap; 00306 00307 // A set of parameter names, to make sure they are declared (?). 00308 // Was map from string to SemTable index 00309 std::set<std::string> ParamSet; 00310 00311 // Parameter (instruction operand, more like addressing mode) details (where given) 00312 std::map<std::string, ParamEntry> DetParamMap; 00313 00314 // The maps which summarise the semantics (.ssl) file 00315 std::map<std::string, Exp*> FlagFuncs; 00316 std::map<std::string, std::pair<int, void*>*> DefMap; 00317 std::map<int, Exp*> AliasMap; 00318 00319 // Map from ordinary instruction to fast pseudo instruction, for use with -f (fast but not as exact) switch 00320 std::map<std::string, std::string> fastMap; 00321 00322 bool bigEndian; // True if this source is big endian 00323 00324 // The actual dictionary. 00325 std::map<std::string, TableEntry, std::less<std::string> > idict; 00326 00327 // An RTL describing the machine's basic fetch-execute cycle 00328 RTL *fetchExecCycle; 00329 00330 void fixupParamsSub(std::string s, std::list<std::string>& funcParams, bool& haveCount, int mark); 00331 }; 00332 00333 #endif /*__RTL_H__*/ 00334