ops.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 OPCODES_H
00020 #define OPCODES_H
00021 
00022 #include <map>
00023 #include <string>
00024 #include <vector>
00025 #include <iostream>
00026 #include <cassert>
00027 #include "Configuration.h"
00028 #include "ucc.h"
00029 
00030 std::vector<std::string> qnd_ocsplit(const std::string &s);
00031 
00032 void map_type_size(const std::vector<std::string> &param_types, std::vector<std::pair<unsigned int, bool> > &param_sizes);
00033 
00034 static inline std::string strip_backticks(const std::string &s)
00035 {
00036   if(s.size()==2 && s[0]=='`' && s[1]=='`')
00037     return std::string();
00038   else if(s[0]=='`' && s[s.size()-1]=='`')
00039     return s.substr(1, s.size()-2);
00040   return s;
00041 }
00042 
00043 /* Just a basic class to tie together half a dozen initialisation routines. */
00044 class ucxtInit
00045 {
00046   public:
00047     ucxtInit(const std::string &new_ucxtdata=std::string("ucxt.data"))
00048       : ucxtdata(new_ucxtdata)
00049     { };
00050     void init(const Configuration &config, const UCOptions &options);
00051     
00052   private:
00053     std::string get_datadir(const Configuration &config, const UCOptions &options);
00054     void misc();
00055     void opcodes();
00056     void intrinsics(const std::string &intrinsics_data, const std::string &intrinsics_root);
00057     
00058     const std::string ucxtdata;
00059     std::string datadir;
00060     
00061     std::string opcodes_data;
00062     std::string opcodes_root;
00063     
00064     std::string misc_data;
00065     std::string misc_root;
00066     
00067     std::string bg_intrinsics_data;
00068     std::string bg_intrinsics_root;
00069     
00070     std::string si_intrinsics_data;
00071     std::string si_intrinsics_root;
00072     
00073 };
00074 
00075 class UCOpcodeData
00076 {
00077   public:
00078     UCOpcodeData() : opcode(0x00), num_bytes(0), num_pop(0),
00079                      num_push(0), call_effect(0), flag_return(false),
00080                      flag_paren(false), flag_indent_inc(false),
00081                      flag_indent_dec(false), flag_indent_tmpinc(false),
00082                      flag_indent_tmpdec(false)
00083     {};
00084     UCOpcodeData(unsigned int op, const Configuration::KeyTypeList &ktl)
00085                    : opcode(op), num_bytes(0), num_pop(0),
00086                      num_push(0), call_effect(0), flag_return(false),
00087                      flag_paren(false), flag_indent_inc(false),
00088                      flag_indent_dec(false), flag_indent_tmpinc(false),
00089                      flag_indent_tmpdec(false)
00090     {
00091       for(Configuration::KeyTypeList::const_iterator k=ktl.begin(); k!=ktl.end(); ++k)
00092       {
00093         switch(k->first[0])
00094         {
00095           case 'a':
00096             if(k->first=="asm_nmo")             asm_nmo = strip_backticks(k->second);
00097             else if(k->first=="asm_comment")    asm_comment = strip_backticks(k->second);
00098             break;
00099           case 'c':
00100             if(k->first=="call_effect")         call_effect = strtol(k->second.c_str(), 0, 0);
00101             break;
00102           case 'i':
00103             if(k->first=="indent_inc/")         flag_indent_inc=true;
00104             else if(k->first=="indent_dec/")    flag_indent_dec=true;
00105             else if(k->first=="indent_tmpinc/") flag_indent_tmpinc=true;
00106             else if(k->first=="indent_tmpdec/") flag_indent_tmpdec=true;
00107             break;
00108           case 'n':
00109             if(k->first=="name")                name = strip_backticks(k->second);
00110             else if(k->first=="num_bytes")      num_bytes = strtol(k->second.c_str(), 0, 0);
00111             else if(k->first=="num_pop")        num_pop = strtol(k->second.c_str(), 0, 0);
00112             else if(k->first=="num_push")       num_push = strtol(k->second.c_str(), 0, 0);
00113             break;
00114           case 'p':
00115             if(k->first=="param_types")         param_types = qnd_ocsplit(k->second);
00116             else if(k->first=="paren/")         flag_paren=true;
00117             break;
00118           case 'r':
00119             if(k->first=="return/")             flag_return=true;
00120             break;
00121           case 'u':
00122             if(k->first=="ucs_nmo")              ucs_nmo = strip_backticks(k->second);
00123             break;
00124           case '!': // ignore, it's a comment or something.
00125             break;
00126           default:
00127             std::cerr << "invalid key `" << k->first << "` value `" << k->second << "`" << std::endl;
00128         }
00129       }
00130       map_type_size(param_types, param_sizes);
00131     };
00132     
00133     UCOpcodeData(const std::vector<std::string> &v)
00134     {
00135       if((v.size()==12)==false)
00136       {
00137         std::cerr << "Error in opcodes file:" << std::endl;
00138         for(unsigned int i=0; i<v.size(); i++)
00139           std::cerr << v[i] << '\t';
00140         std::cerr << std::endl;
00141       }
00142       
00143       assert(v.size()==12);
00144       opcode = strtol(v[1].c_str(), 0, 0);
00145       name = v[2];
00146       asm_nmo = v[3];
00147       asm_comment = v[4];
00148       ucs_nmo = v[5];
00149       num_bytes = strtol(v[6].c_str(), 0, 0);
00150       param_types = qnd_ocsplit(v[7]);
00151       num_pop = strtol(v[8].c_str(), 0, 0);
00152       num_push = strtol(v[9].c_str(), 0, 0);
00153       call_effect = strtol(v[10].c_str(), 0, 0);
00154       assert(v[11].size()>=6);
00155       flag_return        = (v[11][0]=='0') ? false : true;
00156       flag_paren         = (v[11][1]=='0') ? false : true;
00157       flag_indent_inc    = (v[11][2]=='0') ? false : true;
00158       flag_indent_dec    = (v[11][3]=='0') ? false : true;
00159       flag_indent_tmpinc = (v[11][4]=='0') ? false : true;
00160       flag_indent_tmpdec = (v[11][5]=='0') ? false : true;
00161       map_type_size(param_types, param_sizes);
00162     };
00163     
00164     void dump(std::ostream &o)
00165     {
00166       o << "opcode: " << opcode << std::endl;
00167       o << "name: " << name << std::endl;
00168       o << "asm_nmo: " << asm_nmo << std::endl;
00169       o << "asm_comment: " << asm_comment << std::endl;
00170       o << "ucs_nmo: " << ucs_nmo << std::endl;
00171       o << "num_bytes: " << num_bytes << std::endl;
00172       o << "param_types: ";
00173       for(typeof(param_types.begin()) i=param_types.begin(); i!=param_types.end(); i++)
00174         o << *i << ',';
00175       o << std::endl;
00176       o << "num_pop: " << num_pop << std::endl;
00177       o << "num_push: " << num_push << std::endl;
00178       o << "call_effect: " << call_effect << std::endl;
00179       o << "flag_return: " << flag_return << std::endl;
00180       o << "flag_paren: " << flag_paren << std::endl;
00181       o << "flag_indent_inc: " << flag_indent_inc << std::endl;
00182       o << "flag_indent_dec: " << flag_indent_dec << std::endl;
00183       o << "flag_indent_tmpinc: " << flag_indent_tmpinc << std::endl;
00184       o << "flag_indent_tmpdec: " << flag_indent_tmpdec << std::endl;
00185     };
00186     
00187     unsigned int   opcode;
00188     std::string    name;
00189     std::string    asm_nmo;
00190     std::string    asm_comment;
00191     std::string    ucs_nmo;
00192     unsigned int   num_bytes;
00193     
00194     unsigned int   num_pop;
00195     unsigned int   num_push;
00196     unsigned int   call_effect;
00197     bool           flag_return;
00198     bool           flag_paren;
00199     bool           flag_indent_inc;
00200     bool           flag_indent_dec;
00201     bool           flag_indent_tmpinc;
00202     bool           flag_indent_tmpdec;
00203     
00204     std::vector<std::string> param_types;
00205     // values caluclated from param_types
00206     std::vector<std::pair<unsigned int, bool> > param_sizes; // .first==size of parameter in bytes .second==whether to treat it as a relative offset and calculate for it
00207     
00208 };
00209 
00210 extern std::vector<UCOpcodeData> opcode_table_data;
00211 extern std::vector<std::pair<unsigned int, unsigned int> > opcode_jumps;
00212 
00213 extern std::map<unsigned int, std::string> uc_intrinsics;
00214 
00215 #endif
00216 

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