00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "pent_include.h"
00022
00023 #include "IfNode.h"
00024 #include "OperatorNodes.h"
00025 #include "Folder.h"
00026
00027 #include <deque>
00028 using std::deque;
00029
00030
00031
00032
00033
00034
00035
00036 void IfNode::print_unk(Console &o, const uint32 isize) const
00037 {
00038 assert(rtype().type()==Type::T_INVALID);
00039
00040
00041 switch(itype)
00042 {
00043 case I_IF:
00044 case I_IF_ELSE:
00045 case I_IF_ELSE_IF:
00046 break;
00047 case I_ELSE_IF:
00048 case I_ELSE_IF_ELSE:
00049 case I_ELSE:
00050 o.Print("else ");
00051 break;
00052 default: assert(false);
00053 }
00054
00055 switch(itype)
00056 {
00057 case I_IF:
00058 case I_IF_ELSE:
00059 case I_IF_ELSE_IF:
00060 case I_ELSE_IF:
00061 case I_ELSE_IF_ELSE:
00062 assert(node!=0);
00063
00064 o.Print("if(");
00065
00066
00067
00068 o.Print("not ");
00069
00070 node->print_unk(o, isize);
00071 o.Print(")");
00072 break;
00073 case I_ELSE:
00074 break;
00075 default: assert(false);
00076 }
00077 o.Print("\n");
00078 indent(o, isize);
00079 o.Print("{");
00080 Node::print_linenum_unk(o, isize);
00081 #ifdef DEBUG_JUNK
00082 if(itype!=I_ELSE)
00083 o.Printf(" //jne_NOPRINT(0x%04X)", targetOffset);
00084 #endif
00085 o.Print("\n");
00086
00087 for(std::deque<Node *>::const_iterator i=ifnodes.begin(); i!=ifnodes.end(); ++i)
00088 {
00089 indent(o, isize+1);
00090 (*i)->print_unk(o, isize+1);
00091 o.Putchar('\n');
00092 }
00093
00094 indent(o, isize);
00095 o.Putchar('}');
00096 #ifdef DEBUG_JUNK
00097 o.Printf("/*%02X*/", itype);
00098 #endif
00099 switch(itype)
00100 {
00101 case I_IF:
00102 case I_ELSE_IF:
00103 assert(jmpnode==0);
00104 break;
00105 case I_IF_ELSE:
00106 case I_ELSE_IF_ELSE:
00107 case I_IF_ELSE_IF:
00108 assert(jmpnode!=0);
00109 #ifdef DEBUG_JUNK
00110 jmpnode->print_unk(o, isize);
00111 #endif
00112
00113 #ifdef DEBUG_JUNK
00114 if(elsenode!=0) o.Print("/*(elsenode)*/");
00115 #endif
00116
00117
00118
00119
00120
00121
00122
00123 break;
00124 case I_ELSE:
00125 break;
00126 default: assert(false);
00127 }
00128 }
00129
00130 void IfNode::print_asm(Console &o) const
00131 {
00132 assert(rtype().type()==Type::T_INVALID);
00133 switch(itype)
00134 {
00135 case I_IF:
00136 case I_IF_ELSE:
00137 case I_IF_ELSE_IF:
00138 case I_ELSE_IF:
00139 case I_ELSE_IF_ELSE:
00140 {
00141 Node::print_linenum_asm(o);
00142 assert(node!=0);
00143 node->print_asm(o);
00144 o.Putchar('\n');
00145 Node::print_asm(o);
00146 o.Printf("jne\t\t%04Xh\t(to %04X)", targetOffset - _offset - 3, targetOffset);
00147 for(std::deque<Node *>::const_iterator i=ifnodes.begin(); i!=ifnodes.end(); ++i)
00148 {
00149 o.Putchar('\n');
00150 (*i)->print_asm(o);
00151 }
00152 if(jmpnode!=0)
00153 {
00154 o.Putchar('\n');
00155 jmpnode->print_asm(o);
00156 }
00157 break;
00158 }
00159 case I_ELSE:
00160 {
00161 for(std::deque<Node *>::const_iterator i=ifnodes.begin(); i!=ifnodes.end(); ++i)
00162 {
00163 if(i!=ifnodes.begin()) o.Putchar('\n');
00164 (*i)->print_asm(o);
00165 }
00166 break;
00167 }
00168 default: assert(false);
00169 }
00170 }
00171
00172 void IfNode::print_bin(ODequeDataSource &o) const
00173 {
00174 assert(rtype().type()==Type::T_INVALID);
00175 Node::print_linenum_bin(o);
00176 switch(itype)
00177 {
00178 case I_IF:
00179 case I_IF_ELSE:
00180 case I_IF_ELSE_IF:
00181 case I_ELSE_IF:
00182 case I_ELSE_IF_ELSE:
00183 {
00184 assert(node!=0);
00185 node->print_bin(o);
00186 o.write1(0x51);
00187 o.write2(targetOffset - _offset - 3);
00188 if(jmpnode!=0)
00189 jmpnode->print_bin(o);
00190 for(std::deque<Node *>::const_iterator i=ifnodes.begin(); i!=ifnodes.end(); ++i)
00191 {
00192 (*i)->print_bin(o);
00193 }
00194 break;
00195 }
00196 default: assert(false);
00197 }
00198 }
00199
00200 bool IfNode::fold(DCUnit *unit, std::deque<Node *> &nodes)
00201 {
00202
00203
00204
00205
00206 switch(itype)
00207 {
00208
00209 case I_IF:
00210 case I_ELSE_IF:
00211
00212
00213 if(node==0)
00214 {
00215 assert(nodes.size()>0);
00216 grab_n(nodes);
00217 fold_linenum(nodes);
00218
00219
00220 if( nodes.size()>0 && nodes.back()->opcode()==0x51)
00221 {
00222
00223 IfNode *n=static_cast<IfNode *>(nodes.back());
00224
00225
00226
00227
00228 assert(n!=this);
00229 switch(n->itype)
00230 {
00231 case I_IF: n->itype=I_IF_ELSE; break;
00232 case I_IF_ELSE: n->itype=I_IF_ELSE_IF; break;
00233 case I_ELSE_IF_ELSE: break;
00234
00235 default: assert(print_assert(this, unit));
00236 }
00237 switch(itype)
00238 {
00239 case I_IF: itype=I_ELSE_IF; break;
00240 default: assert(print_assert(this, unit));
00241 }
00242 }
00243 }
00244
00245
00246
00247
00248
00249
00250 else if(jmpnode==0 && ifnodes.size()>0 && ifnodes.back()->opcode()==0x52)
00251 {
00252 jmpnode=static_cast<EndNode *>(ifnodes.back());
00253 ifnodes.pop_back();
00254 switch(itype)
00255 {
00256 case I_IF: itype = I_IF_ELSE; break;
00257 case I_ELSE_IF: itype = I_ELSE_IF_ELSE; break;
00258 default: assert(print_assert(this, unit));
00259 }
00260 }
00261
00262
00263 break;
00264 break;
00265 case I_IF_ELSE:
00266 case I_IF_ELSE_IF:
00267 case I_ELSE_IF_ELSE:
00268 break;
00269 default: assert(print_assert(this, unit));
00270 }
00271
00272 return true;
00273 }
00274
00275 bool IfNode::fold_else(DCUnit *unit, std::deque<Node *> &nodes)
00276 {
00277 switch(itype)
00278 {
00279 case I_ELSE:
00280 if(ifnodes.size()==0)
00281 {
00282 bool finished=false;
00283 while(!finished)
00284 {
00285 assert(nodes.size()>0 || print_assert(this, unit));
00286 if(nodes.back()->opcode()==0x51 || nodes.back()->opcode()==0x52)
00287 if(static_cast<IfNode *>(nodes.back())->TargetOffset()==TargetOffset())
00288 finished=true;
00289
00290 if(!finished)
00291 {
00292 ifnodes.push_front(nodes.back());
00293 nodes.pop_back();
00294 }
00295 if(nodes.size()==0)
00296 finished = true;
00297 }
00298 }
00299 break;
00300 default: assert(print_assert(this, unit));
00301 }
00302 return false;
00303 }
00304
00305
00306
00307
00308
00309 void EndNode::print_unk(Console &o, const uint32 isize) const
00310 {
00311 assert(rtype().type()==Type::T_INVALID);
00312 Node::print_linenum_unk(o, isize);
00313 switch(etype)
00314 {
00315 case JMP:
00316 o.Printf("/*jmp_NOPRINT(0x%04X)*/", targetOffset);
00317 break;
00318 default: assert(false);
00319 }
00320 }
00321
00322 void EndNode::print_asm(Console &o) const
00323 {
00324 assert(rtype().type()==Type::T_INVALID);
00325 Node::print_linenum_asm(o);
00326 switch(etype)
00327 {
00328 case JMP:
00329 Node::print_asm(o);
00330 o.Printf("jmp\t\t%04Xh\t(to %04X)", targetOffset - _offset - 3, targetOffset);
00331 break;
00332 default: assert(false);
00333 }
00334 }
00335
00336 void EndNode::print_bin(ODequeDataSource &o) const
00337 {
00338 assert(rtype().type()==Type::T_INVALID);
00339 Node::print_linenum_bin(o);
00340 switch(etype)
00341 {
00342 case JMP:
00343 o.write1(0x52);
00344 o.write2(targetOffset - _offset - 3);
00345 break;
00346 default: assert(false);
00347 }
00348 }
00349
00350 bool EndNode::fold(DCUnit * , std::deque<Node *> &nodes)
00351 {
00352 fold_linenum(nodes);
00353
00354 return true;
00355 }
00356