ucfunc.h

Go to the documentation of this file.
00001 /*
00002  *  Copyright (C) 2001-2002  The Exult Team
00003  *
00004  *  This program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  This program is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License
00015  *  along with this program; if not, write to the Free Software
00016  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017  */
00018 
00019 #ifndef UCFUNC_H
00020 #define UCFUNC_H
00021 
00022 #include <map>
00023 #include <vector>
00024 #include <cstdio>
00025 #include <string>
00026 #include <fstream>
00027 #include "ucc.h"
00028 
00029 class UCFuncSet
00030 {
00031   public:
00032     UCFuncSet(unsigned int new_funcid, unsigned int new_num_args, bool new_return_var, const std::string &new_funcname)
00033              : funcid(new_funcid), num_args(new_num_args), return_var(new_return_var), funcname(new_funcname) {};
00034     ~UCFuncSet() {};
00035     
00036     unsigned int funcid;      // the id of the function
00037     unsigned int num_args;    // the number of arguments
00038     bool         return_var;  // if true, the function returns a variable
00039     std::string  funcname;    // the name of the function, if it has one
00040 };
00041 
00042 typedef std::map<unsigned int, UCFuncSet> FuncMap;
00043 typedef std::pair<unsigned int, UCFuncSet> FuncMapPair; 
00044 
00045 //#define DEBUG_GOTOSET
00046 const unsigned int SIZEOF_USHORT = 2;
00047 
00048 class FlagData
00049 {
00050   public:
00051     enum { SETFLAG=false, GETFLAG=true };
00052     /* SETFLAG=UCC_POPF, GETFLAG=UCC_PUSHF */
00053     enum { POP=false, PUSH=true};
00054 
00055     FlagData(const long func, const unsigned int offset,
00056              const unsigned int flag, const bool access)
00057             : _func(func), _offset(offset), _flag(flag), _access(access) {};
00058 
00059     long         func() const { return _func; };
00060     unsigned int offset() const { return _offset; };
00061     unsigned int flag() const { return _flag; };
00062     bool         access() const { return _access; };
00063 
00064   private:
00065     long         _func;
00066     unsigned int _offset;
00067     unsigned int _flag;
00068     bool         _access;
00069 };
00070 
00071 class SortFlagDataLessFlag
00072 {
00073   public:
00074     bool operator()(const FlagData &fd1, const FlagData &fd2) const
00075     {
00076        return (fd1.flag()<fd2.flag()) ? true :
00077                   (fd1.flag()>fd2.flag()) ? false :
00078                       (fd1.func()<fd2.func()) ? true :
00079                           (fd1.func()>fd2.func()) ? false :
00080                               (fd1.offset()<fd2.offset());
00081     };
00082     bool operator()(const FlagData *fd1, const FlagData *fd2) const
00083     {
00084        return (fd1->flag()<fd2->flag()) ? true :
00085                   (fd1->flag()>fd2->flag()) ? false :
00086                       (fd1->func()<fd2->func()) ? true :
00087                           (fd1->func()>fd2->func()) ? false :
00088                               (fd1->offset()<fd2->offset());
00089     };
00090 };
00091 
00092 class SortFlagDataLessFunc
00093 {
00094   public:
00095     bool operator()(const FlagData &fd1, const FlagData &fd2) const
00096     {
00097        return (fd1.func()<fd2.func()) ? true :
00098                   (fd1.func()>fd2.func()) ? false :
00099                       (fd1.flag()<fd2.flag()) ? true :
00100                           (fd1.flag()>fd2.flag()) ? false :
00101                               (fd1.offset()<fd2.offset());
00102     };
00103     bool operator()(const FlagData *fd1, const FlagData *fd2) const
00104     {
00105        return (fd1->func()<fd2->func()) ? true :
00106                   (fd1->func()>fd2->func()) ? false :
00107                       (fd1->flag()<fd2->flag()) ? true :
00108                           (fd1->flag()>fd2->flag()) ? false :
00109                               (fd1->offset()<fd2->offset());
00110     };
00111 };
00112 
00113 class UCNode;
00114 
00115 class UCNode
00116 {
00117   public:
00118     UCNode(UCc *newucc=0) : ucc(newucc) { };
00119     ~UCNode() { };
00120   
00121     UCc *ucc;
00122     std::vector<UCNode *> nodelist;
00123 };
00124 
00125 #include "ops.h"
00126 
00127 class GotoSet
00128 {
00129   public:
00130     GotoSet() : _offset(0) {};
00131     GotoSet(const unsigned int offset, UCc *ucc)
00132            : _offset(offset)
00133     {
00134       add(ucc);
00135     };
00136     GotoSet(UCc *ucc) : _offset(ucc->_offset) { add(ucc); };
00137 
00138     std::vector<std::pair<UCc *, bool> > &operator()() { return _uccs; };
00139     
00140     UCc &operator[](const unsigned int i) { return *(_uccs[i].first); };
00141     unsigned int size() const { return _uccs.size(); };
00142 
00143     void add(UCc *ucc, bool gc=false)
00144     {
00145       _uccs.push_back(std::pair<UCc *, bool>(ucc, gc));
00146     };
00147 
00148     /* Just a quick function to remove all the Uccs in _uccs marked for
00149        garbage collection. */
00150     void gc()
00151     {
00152       for(GotoSet::iterator j=_uccs.begin(); j!=_uccs.end();)
00153       {
00154         #ifdef DEBUG_GOTOSET
00155         std::cout << "OP: " << opcode_table_data[j->first->_id].ucs_nmo << '\t' << j->second;
00156         #endif
00157         if(j->second==true)
00158         {
00159           /* ok, we need to take into consideration that the
00160              iterator we're removing might ==_uccs.begin() */
00161           bool begin=false;
00162           if(j==_uccs.begin()) begin=true;
00163           
00164           #ifdef DEBUG_GOTOSET
00165           std::cout << "\tremoved";
00166           #endif
00167           
00168           GotoSet::iterator rem(j);
00169           
00170           if(begin==false) j--;
00171           
00172           _uccs.erase(rem);
00173           
00174           if(begin==true) j=_uccs.begin();
00175           else            j++;
00176           
00177           if(j==_uccs.end()) std::cout << "POTENTIAL PROBLEM" << std::endl;
00178         }
00179         else
00180           j++;
00181         
00182         #ifdef DEBUG_GOTOSET
00183         std::cout << std::endl;
00184         #endif
00185       }
00186     };
00187     
00188     unsigned int offset() const { return _offset; };
00189 
00190     typedef std::vector<std::pair<UCc *, bool> >::iterator iterator;
00191     
00192   private:
00193     unsigned int _offset;
00194     std::vector<std::pair<UCc *, bool> > _uccs;
00195 };
00196 
00197 class UCOpcodeData;
00198 
00199 class UCFunc
00200 {
00201   public:
00202     UCFunc() : _offset(0), _funcid(0), _funcsize(0), _bodyoffset(0), _datasize(0),
00203                _codeoffset(0), _num_args(0), _num_locals(0), _num_externs(0),
00204                return_var(false), debugging_info(false), debugging_offset(0), ext32(false) {};
00205 
00206     bool output_list(std::ostream &o, unsigned int funcno, const UCOptions &options);
00207     
00208     bool output_ucs(std::ostream &o, const FuncMap &funcmap, const std::map<unsigned int, std::string> &intrinsics, const UCOptions &options);
00209     std::ostream &output_ucs_funcname(std::ostream &o, const FuncMap &funcmap);
00210     std::ostream &output_ucs_funcname(std::ostream &o, const FuncMap &funcmap,
00211                                     unsigned int funcid,
00212                                     unsigned int numargs, bool return_var);
00213     void output_ucs_node(std::ostream &o, const FuncMap &funcmap, UCNode* ucn, const std::map<unsigned int, std::string> &intrinsics, unsigned int indent, const UCOptions &options);
00214     void output_ucs_data(std::ostream &o, const FuncMap &funcmap, const std::map<unsigned int, std::string> &intrinsics, const UCOptions &options, unsigned int indent);
00215     void output_ucs_opcode(std::ostream &o, const FuncMap &funcmap, const std::vector<UCOpcodeData> &optab, const UCc &op, const std::map<unsigned int, std::string> &intrinsics, unsigned int indent);
00216     
00217     void parse_ucs(const FuncMap &funcmap, const std::map<unsigned int, std::string> &intrinsics, const UCOptions &options);
00218     void parse_ucs_pass1(std::vector<UCNode *> &nodes);
00219     void parse_ucs_pass2(std::vector<GotoSet> &gotoset, const FuncMap &funcmap, const std::map<unsigned int, std::string> &intrinsics);
00220     std::vector<UCc *> parse_ucs_pass2a(std::vector<std::pair<UCc *, bool> >::reverse_iterator current,
00221                                    std::vector<std::pair<UCc *, bool> > &vec, unsigned int opsneeded,
00222                                    const FuncMap &funcmap, const std::map<unsigned int, std::string> &intrinsics);
00223     void parse_ucs_pass3(std::vector<GotoSet> &gotoset, const std::map<unsigned int, std::string> &intrinsics);
00224 
00225     bool output_asm(std::ostream &o, const FuncMap &funcmap, const std::map<unsigned int, std::string> &intrinsics, const UCOptions &options);
00226     void output_asm_data(std::ostream &o);
00227     void output_asm_opcode(std::ostream &o, const FuncMap &funcmap, const std::vector<UCOpcodeData> &optab, const std::map<unsigned int, std::string> &intrinsics, const UCc &op, const UCOptions &options);
00228     void output_raw_opcodes(std::ostream &o, const UCc &op);
00229     
00230     bool output_tt(std::ostream &o);
00231 
00232 //  private:
00233   
00234     std::vector<GotoSet> gotoset;
00235     
00236     std::streampos _offset;      // offset to start of function
00237     unsigned int   _funcid;      // the id of the function
00238     unsigned int   _funcsize;    // the size of the function (bytes)
00239     std::streampos _bodyoffset;  // the file position after the header is read
00240     
00241     unsigned int   _datasize;    // the size of the data block
00242     
00243     std::map<unsigned int, std::string, std::less<unsigned int> > _data;
00244       // contains the entire data segment in offset from start of segment, and string data pairs
00245     
00246     std::streampos _codeoffset; // the offset to the start of the code segment
00247     
00248     unsigned int   _num_args;    // the number of arguments
00249     unsigned int   _num_locals;  // the number of local variables
00250     unsigned int   _num_externs; // the number of external function id's
00251     std::vector<unsigned int> _externs; // the external function id's
00252     
00253     std::vector<UCc> _opcodes;
00254     
00255     bool           return_var; // does the function return a variable?
00256     bool           debugging_info;
00257     unsigned int   debugging_offset;
00258     std::string    funcname;
00259     
00260     bool           ext32; // is this function an extended function?
00261     
00262     unsigned int codesize() const { return _funcsize - _datasize; };
00263     
00264     UCNode node;
00265 };
00266 
00267 void readbin_U7UCFunc(std::ifstream &f, UCFunc &ucf, const UCOptions &options);
00268 void readbin_U8UCFunc(std::ifstream &f, UCFunc &ucf);
00269 
00270 #endif
00271 

Generated on Mon Jul 9 14:42:52 2007 for ExultEngine by  doxygen 1.5.1