VarNodes.cpp

Go to the documentation of this file.
00001 /*
00002  *      VarNodes.cpp -
00003  *
00004  *  Copyright (C) 2002-2003 The Pentagram Team
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00019  */
00020 
00021 #include "pent_include.h"
00022 
00023 #include "VarNodes.h"
00024 
00025 /****************************************************************************
00026         PopVarNode
00027  ****************************************************************************/
00028 
00029 /*void PopVarNode::fold(const uint32 end)
00030 {
00031         PTRACE(("(PopVar)\tPOS: %4d\tOP: %04X offset: %04X\n", end, foldops[end].op(),
00032                 foldops[end].offset));
00033         assert(foldops[end].deleted==false);
00034 
00035         _opcode = foldops[end].op(); // store the op locally
00036         _offset = foldops[end].offset; // store the offset locally
00037 
00038         switch(_opcode)
00039         {
00040                 case 0x00: // popping a byte (1 byte)
00041                         lnode  = new PushVarNode(PushVarNode::VT_BYTE, PushVarNode::DT_BP,
00042                                 foldops[end].i0);
00043                         rtype=Type::T_VOID;
00044                         break;
00045                 case 0x01: // popping a word (2 bytes)
00046                         lnode  = new PushVarNode(PushVarNode::VT_WORD, PushVarNode::DT_BP,
00047                                 foldops[end].i0);
00048                         rtype=Type::T_VOID;
00049                         break;
00050                 case 0x02: // popping a dword (4 bytes)
00051                         lnode  = new PushVarNode(PushVarNode::VT_DWORD, PushVarNode::DT_BP,
00052                                 foldops[end].i0);
00053                         rtype=Type::T_VOID;
00054                         break;
00055                 case 0x08: // popping a result (4 bytes)
00056                         lnode  = new PushVarNode(PushVarNode::VT_DWORD, PushVarNode::DT_RESULT, 0);
00057                         rtype=Type::T_VOID;
00058                         break;
00059                 default: // die if we don't know the op
00060                         printf("\nopcode %02X not supported in call to PopVarNode from offset %04X\n",
00061                                 _opcode, _offset);
00062                         //printfolding();
00063                         assert(false);
00064                         break;
00065         }
00066 
00067         sint32 tempsize = lnode->rtype.size();
00068         assert(tempsize>0);
00069         grab_r(tempsize, end);
00070         assert(tempsize==0);
00071 }*/
00072 
00073 
00074 void PopVarNode::print_unk(Console &o, const uint32 isize) const
00075 {
00076         assert(node!=0);
00077         Node::print_linenum_unk(o, isize);
00078         #if 0
00079         _dtype.print_type_unk(o);
00080         o.Putchar(' ');
00081         #endif
00082         _dtype.print_value_unk(o);
00083         o.Print(" = ");
00084         node->print_unk(o, isize);
00085 }
00086 
00087 void PopVarNode::print_asm(Console &o) const
00088 {
00089         assert(node!=0);
00090         Node::print_linenum_asm(o);
00091         node->print_asm(o);
00092         o.Putchar('\n');
00093         Node::print_asm(o);
00094         switch(_dtype.dtype())
00095         {
00096                 case DataType::DT_BP:
00097                         switch(_dtype.type().type())
00098                         {
00099                                 case Type::T_WORD:  o.Printf("pop\t\t");     _dtype.print_value_asm(o); break;
00100                                 //case Type::T_DWORD: o.Printf("pop dword\t"); _dtype.print_value_asm(o); break;
00101                                 default: assert(false);
00102                         }
00103                         break;
00104                 case DataType::DT_TEMP:
00105                         switch(_dtype.type().type())
00106                         {
00107                                 case Type::T_WORD:  o.Printf("pop\t\ttemp"); break;
00108                                 default: assert(false);
00109                         }
00110                         break;
00111                 default: assert(false);
00112         }
00113 }
00114 
00115 void PopVarNode::print_bin(ODequeDataSource  &o) const
00116 {
00117         assert(node!=0);
00118         Node::print_linenum_bin(o);
00119         node->print_bin(o);
00120         switch(_dtype.dtype())
00121         {
00122                 case DataType::DT_BP:
00123                         switch(_dtype.type().type())
00124                         {
00125                                 case Type::T_WORD:  o.write1(0x01); _dtype.print_value_bin(o); break;
00126                                 default: assert(false);
00127                         }
00128                         break;
00129                 case DataType::DT_TEMP:
00130                         switch(_dtype.type().type())
00131                         {
00132                                 case Type::T_WORD:  o.write1(0x12); break;
00133                                 default: assert(false);
00134                         }
00135                         break;
00136                 default: assert(false);
00137         }
00138 }
00139 
00140 bool PopVarNode::fold(DCUnit *unit, std::deque<Node *> &nodes)
00141 {
00142         //con.Printf("RTypes: %d %d", nodes.back()->rtype().type(), rtype().type());
00143         assert(nodes.back()->rtype()==rtype() || print_assert(this, unit));
00144         grab_n(nodes);
00145         fold_linenum(nodes);
00146         return true;
00147 }
00148 
00149 
00150 /****************************************************************************
00151         PushVarNode
00152  ****************************************************************************/
00153 
00154 /*void PushVarNode::fold(const uint32 end)
00155 {
00156         PTRACE(("(PushVar)\tPOS: %4d\tOP: %04X offset: %04X\n", end, foldops[end].op(),
00157                 foldops[end].offset));
00158         assert(foldops[end].deleted==false);*/
00159 
00160 /*      _opcode = foldops[end].op(); // store the op locally
00161         _offset = foldops[end].offset; // store the offset locally
00162 */
00163 /*      switch(_opcode)
00164         {
00165                 case 0x0D: // pushing a string (2 bytes)
00166                         _vtype = VT_STRING;
00167                         _dtype  = DT_CHARS;
00168                         strval = foldops[end].str;
00169                         rtype=Type::T_STRING;
00170                         break;
00171                 case 0x3E: // pushing a byte var (2 bytes)
00172                         _vtype  = VT_BYTE;
00173                         _dtype  = DT_BP;
00174                         value  = foldops[end].i0;
00175                         rtype=Type::T_BYTE;
00176                         break;
00177                 case 0x3F: // pushing a word var (2 bytes)
00178                         _vtype  = VT_WORD;
00179                         _dtype  = DT_BP;
00180                         value  = foldops[end].i0;
00181                         rtype=Type::T_WORD;
00182                         break;
00183                 case 0x41: // pushing a string var (2 bytes)
00184                         _vtype = VT_STRING;
00185                         _dtype  = DT_BP;
00186                         value  = foldops[end].i0;
00187                         rtype=Type::T_STRING;
00188                         break;
00189                 case 0x42: // pushing a list (2 bytes?)
00190                         _vtype = VT_LIST;
00191                         _dtype  = DT_BPLIST;
00192                         value  = foldops[end].i0;
00193                         value2 = foldops[end].i1;
00194                         assert(value2==2); // FIXME: incorrect, but a quick hack for my purposes
00195                         rtype=Type::T_LIST;
00196                         break;
00197                 case 0x43: // pushing a slist (2 bytes?)
00198                         _vtype  = VT_SLIST;
00199                         _dtype  = DT_BP;
00200                         value  = foldops[end].i0;
00201                         rtype=Type::T_SLIST;
00202                         break;
00203                 case 0x4E: // pushing a global (x bytes - round up to an even pair of bytes
00204                         _dtype  = DT_GLOBAL;
00205                         global_offset = foldops[end].i0;
00206                         global_size   = foldops[end].i1;
00207                         switch(global_size)
00208                         {
00209                                 case 0x01: _vtype = VT_BYTE;  rtype=Type::T_BYTE; break;
00210                                 case 0x02: _vtype = VT_WORD;  rtype=Type::T_WORD; break;
00211                                 case 0x03: _vtype = VT_DWORD; rtype=Type::T_DWORD; break;
00212 //                              case 0x04: _vtype = DWORD; rtype=Type::T_DWORD; break;
00213                                 // debugging, remove this and replace it with a _vtype=VAR when finished
00214                                 default: assert(false);
00215                         }
00216                         break;
00217                 case 0x59: // pushing a pid (2 bytes - maybe)
00218                         _vtype  = VT_VPID;
00219                         _dtype  = DT_DPID;
00220                         value  = 0; // unused
00221                         rtype=Type::T_PID;
00222                         break;
00223                 case 0x69: // pushing a string ptr (4 bytes)
00224                         _vtype = VT_DWORD;
00225                         _dtype  = DT_BPSTRPTR;
00226                         value  = 0x100-foldops[end].i0;
00227                         rtype=Type::T_DWORD;
00228                         break;
00229                 case 0x6D: // pushing an address of a SP (4 bytes)
00230                         _vtype = VT_DWORD;
00231                         _dtype  = DT_PRESULT;
00232                         value  = 0; // unused
00233                         rtype=Type::T_DWORD;
00234                         break;
00235                 case 0x6F: // pushing an address of a SP (4 bytes)
00236                         _vtype = VT_DWORD;
00237                         _dtype  = DT_SPADDR;
00238                         value  = 0x100-foldops[end].i0;
00239                         rtype=Type::T_DWORD;
00240                         break;
00241                 case 0x79: // pushing a global address (4 bytes)
00242                         if(crusader) // we're only a global for crusader
00243                         {
00244                                 _vtype = VT_DWORD;
00245                                 _dtype  = DT_SPADDR;
00246                                 value  = 0x100-foldops[end].i0;
00247                                 rtype=Type::T_DWORD;
00248                         }
00249                         else // not for u8
00250                                 assert(false);
00251                         break;
00252                 default: // die if we don't know the op
00253                         printf("\nopcode %02X not supported in call to PushVarNode from offset %04X\n",
00254                                 _opcode, _offset);
00255                         //printfolding();
00256                         assert(false);
00257                         break;
00258         }
00259 }*/
00260 
00261 void PushVarNode::print_unk(Console &o, const uint32 /*isize*/) const
00262 {
00263         #if 0
00264         _dtype.print_type_unk(o);
00265         o.Putchar(' ');
00266         #endif
00267         _dtype.print_value_unk(o);
00268 }
00269 
00270 void PushVarNode::print_asm(Console &o) const
00271 {
00272         Node::print_asm(o);
00273         switch(_dtype.dtype())
00274         {
00275                 case DataType::DT_BYTES:
00276                         switch(_dtype.type().type())
00277                         {
00278                                 case Type::T_BYTE:  o.Printf("push byte\t");  _dtype.print_value_asm(o); break;
00279                                 case Type::T_WORD:  o.Printf("push\t\t");     _dtype.print_value_asm(o); break;
00280                                 case Type::T_DWORD: o.Printf("push dword\t"); _dtype.print_value_asm(o); break;
00281                                 default: assert(false); // can't happen
00282                         }
00283                         break;
00284                 case DataType::DT_BP:
00285                         switch(_dtype.type().type())
00286                         {
00287                                 case Type::T_WORD:  o.Printf("push\t\t");     _dtype.print_value_asm(o); break;
00288                                 case Type::T_DWORD: o.Printf("push dword\t"); _dtype.print_value_asm(o); break;
00289                                 default: assert(false);
00290                         }
00291                         break;
00292                 case DataType::DT_BPADDR:
00293                         switch(_dtype.type().type())
00294                         {
00295                                 case Type::T_DWORD: o.Printf("push addr\t"); _dtype.print_value_asm(o); break;
00296                                 default: assert(false); // can't happen
00297                         }
00298                         break;
00299                 case DataType::DT_STRING:
00300                         switch(_dtype.type().type())
00301                         {
00302                                 case Type::T_STRING: o.Printf("push string\t"); _dtype.print_value_asm(o); break;
00303                                 default: assert(false); // can't happen
00304                         }
00305                         break;
00306                 case DataType::DT_PID:
00307                         //assert(_dtype.type().type()==Type::T_PID);
00308                         o.Printf("push\t\tpid");
00309                         break;
00310                 case DataType::DT_GLOBAL:
00311                         assert(_dtype.type().type()==Type::T_WORD);
00312                         o.Printf("push\t\tglobal ");
00313                         _dtype.print_value_asm(o);
00314                         break;
00315                 default: assert(false);
00316         }
00317 }
00318 
00319 void PushVarNode::print_bin(ODequeDataSource  &o) const
00320 {
00321         switch(_dtype.dtype())
00322         {
00323                 case DataType::DT_BYTES:
00324                         switch(_dtype.type().type())
00325                         {
00326                                 case Type::T_BYTE:  o.write1(0x0A); _dtype.print_value_bin(o); break;
00327                                 case Type::T_WORD:  o.write1(0x0B); _dtype.print_value_bin(o); break;
00328                                 case Type::T_DWORD: o.write1(0x0C); _dtype.print_value_bin(o); break;
00329                                 default: assert(false); // can't happen
00330                         }
00331                         break;
00332                 case DataType::DT_BP:
00333                         switch(_dtype.type().type())
00334                         {
00335                                 case Type::T_WORD:  o.write1(0x3F); _dtype.print_value_bin(o); break;
00336                                 case Type::T_DWORD: o.write1(0x40); _dtype.print_value_bin(o); break;
00337                                 default: assert(false);
00338                         }
00339                         break;
00340                 case DataType::DT_BPADDR:
00341                         switch(_dtype.type().type())
00342                         {
00343                                 case Type::T_DWORD: o.write1(0x4B); _dtype.print_value_bin(o); break;
00344                                 default: assert(false); // can't happen
00345                         }
00346                         break;
00347                 case DataType::DT_STRING:
00348                         switch(_dtype.type().type())
00349                         {
00350                                 case Type::T_STRING: o.write1(0x0D); _dtype.print_value_bin(o); break;
00351                                 default: assert(false); // can't happen
00352                         }
00353                         break;
00354                 case DataType::DT_PID:
00355                         o.write1(0x59);
00356                         break;
00357                 case DataType::DT_GLOBAL:
00358                         assert(_dtype.type().type()==Type::T_WORD);
00359                         o.write1(0x4E);
00360                         _dtype.print_value_bin(o); break;
00361                         break;
00362                 default: assert(false);
00363         }
00364 }
00365 

Generated on Fri Jul 27 22:27:52 2007 for pentagram by  doxygen 1.4.7