00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef GENERICNODES_H
00022 #define GENERICNODES_H
00023
00024 #include "Type.h"
00025
00026 #include <deque>
00027 #include <vector>
00028 #include "Console.h"
00029
00030
00031 #define FOR_CONST_DEQUE(CLAS, DEQ, I) for(std::deque<CLAS *>::const_iterator I=(DEQ).begin(); (I)!=DEQ.end(); ++(I))
00032 #define FOR_CONST_SET(CLAS, SET, I) for(std::set<CLAS *>::const_iterator I=(SET).begin(); (I)!=SET.end(); ++(I))
00033
00034 class DCUnit;
00035
00036 inline bool acceptOp(const uint32 opcode, const uint32 want1)
00037 { return ((opcode==want1) ? true : false); };
00038 inline bool acceptOp(const uint32 opcode, const uint32 want1, const uint32 want2)
00039 { return (acceptOp(opcode, want1) ? true :
00040 (opcode==want2) ? true : false); };
00041 inline bool acceptOp(const uint32 opcode, const uint32 want1, const uint32 want2, const uint32 want3)
00042 { return (acceptOp(opcode, want1, want2) ? true :
00043 (opcode==want3) ? true : false); };
00044 inline bool acceptOp(const uint32 opcode, const uint32 want1, const uint32 want2, const uint32 want3, const uint32 want4)
00045 { return (acceptOp(opcode, want1, want2, want3) ? true :
00046 (opcode==want4) ? true : false); };
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 inline void indent(Console &o, uint32 size)
00059 {
00060 switch(size) {
00061 case 0: break;
00062 case 1: o.Print("\t"); break;
00063 case 2: o.Print("\t\t"); break;
00064 case 3: o.Print("\t\t\t"); break;
00065 case 4: o.Print("\t\t\t\t"); break;
00066 case 5: o.Print("\t\t\t\t\t"); break;
00067 case 6: o.Print("\t\t\t\t\t\t"); break;
00068 case 7: o.Print("\t\t\t\t\t\t\t"); break;
00069 case 8: o.Print("\t\t\t\t\t\t\t\t"); break;
00070 case 9: o.Print("\t\t\t\t\t\t\t\t\t"); break;
00071 default: assert(false);
00072 }
00073 }
00074
00075 class PrintHelperNode
00076 {
00077 public:
00078 inline void print_asm_header(Console &o, const uint32 h_off, const uint32 h_op) const
00079 {
00080 o.Printf(" %04X: %02X\t", h_off, h_op);
00081 }
00082 inline void print_mac_header(Console &o, const uint32 h_off, const uint32 h_op) const
00083 {
00084 o.Printf(" (%04X: %02X)\t", h_off, h_op);
00085 }
00086
00087 };
00088
00089 class Node;
00090
00091
00092
00093
00094
00095 class Node : public PrintHelperNode
00096 {
00097 public:
00098 Node(const sint32 newOpcode=-1, const uint32 newOffset=0, const Type newRType=Type())
00099 : _opcode(newOpcode), _offset(newOffset), _rtype(newRType), linenum(0) {};
00100 virtual ~Node() {};
00101
00102 inline sint32 opcode() const { return _opcode; };
00103 inline uint32 offset() const { return _offset; };
00104
00105 inline const Type &rtype() const { return _rtype; };
00106 inline void rtype(const Type &newRType) { _rtype=newRType; };
00107
00108
00109
00110
00111
00112
00113
00114
00115 virtual bool fold(DCUnit *unit, std::deque<Node *> &nodes)=0;
00116
00117
00118 virtual void print_unk(Console &o, const uint32 isize) const=0;
00119
00120 virtual void print_asm(Console &o) const;
00121
00122 virtual void print_mac(Console &o) const;
00123
00124 virtual void print_bin(ODequeDataSource &o) const=0;
00125
00126 inline void fold_linenum(std::deque<Node *> &nodes);
00127
00128 inline void print_linenum_unk(Console &o, const uint32 isize) const;
00129 inline void print_linenum_asm(Console &o) const;
00130 inline void print_linenum_bin(ODequeDataSource &o) const;
00131
00132
00133
00134
00135 protected:
00136 Node *grab(std::deque<Node *> &nodes)
00137 {
00138 assert(nodes.size()>0);
00139 Node *n = nodes.back();
00140 nodes.pop_back();
00141 return n;
00142 };
00143
00144 sint32 _opcode;
00145 uint32 _offset;
00146 Type _rtype;
00147 Node *linenum;
00148
00149 private:
00150 };
00151
00152 inline void Node::print_asm(Console &o) const
00153 {
00154 print_asm_header(o, _offset, _opcode);
00155 }
00156
00157 inline void Node::print_mac(Console &o) const
00158 {
00159 print_mac_header(o, _offset, _opcode);
00160 }
00161
00162 inline void Node::print_linenum_unk(Console &o, const uint32 isize) const
00163 {
00164 if(linenum!=0)
00165 {
00166 linenum->print_unk(o, isize);
00167 }
00168 }
00169
00170 inline void Node::print_linenum_asm(Console &o) const
00171 {
00172 if(linenum!=0)
00173 {
00174 linenum->print_asm(o);
00175 o.Putchar('\n');
00176 }
00177 }
00178
00179 inline void Node::print_linenum_bin(ODequeDataSource &o) const
00180 {
00181 if(linenum!=0) linenum->print_bin(o);
00182 }
00183
00184 inline void Node::fold_linenum(std::deque<Node *> &nodes)
00185 {
00186
00187 if(nodes.size()==0)
00188 return;
00189
00190 if(opcode()==0x5B)
00191 return;
00192
00193
00194
00195
00196 if(linenum==0)
00197 {
00198 Node *tnode=0;
00199
00200
00201 if(nodes.back()->offset()==offset())
00202 {
00203 tnode = nodes.back();
00204 nodes.pop_back();
00205 }
00206
00207
00208 if(nodes.size()>0)
00209 if(acceptOp(nodes.back()->opcode(), 0x5B))
00210 {
00211 linenum = nodes.back();
00212 nodes.pop_back();
00213 }
00214
00215 if(tnode!=0)
00216 nodes.push_back(tnode);
00217 }
00218 }
00219
00220
00221
00222
00223
00224
00225 class UniNode : public Node
00226 {
00227 public:
00228 UniNode(const sint32 newOpcode=-1, const uint32 newOffset=0,
00229 const Type newRType=Type())
00230 : Node(newOpcode, newOffset, newRType), node(0) {};
00231 virtual ~UniNode() { };
00232
00233 protected:
00234 void grab_n(std::deque<Node *> &nodes) { node=grab(nodes); };
00235 Node *node;
00236
00237 private:
00238 };
00239
00240
00241
00242
00243
00244
00245 class BinNode : public Node
00246 {
00247 public:
00248 BinNode(const sint32 newOpcode=-1, const uint32 newOffset=0,
00249 const Type newRType=Type())
00250 : Node(newOpcode, newOffset, newRType), lnode(0), rnode(0) {};
00251 virtual ~BinNode() { };
00252
00253 protected:
00254 void grab_l(std::deque<Node *> &nodes) { lnode=grab(nodes); };
00255 void grab_r(std::deque<Node *> &nodes) { rnode=grab(nodes); };
00256
00257 Node *lnode;
00258 Node *rnode;
00259
00260 private:
00261 };
00262
00263
00264
00265
00266
00267
00268
00269 class ColNode : public Node
00270 {
00271 public:
00272 ColNode(const sint32 newOpcode=-1, const uint32 newOffset=0,
00273 const Type newRType=Type())
00274 : Node(newOpcode, newOffset, newRType), pnode(0) {};
00275 virtual ~ColNode() {};
00276
00277 protected:
00278 void grab_p(std::deque<Node *> &nodes, sint32 tempsize)
00279 {
00280 while(tempsize>0)
00281 {
00282 con.Printf("tempsize=%d\n", tempsize);
00283 pnode.push_back(grab(nodes));
00284 con.Printf("nodesize=%d\n", pnode.back()->rtype().size());
00285 pnode.back()->print_asm(con);
00286 tempsize-=pnode.back()->rtype().size();
00287 }
00288 assert(tempsize==0);
00289 };
00290
00291 std::deque<Node *> pnode;
00292
00293 private:
00294 };
00295
00296
00297
00298
00299
00300
00301 class DCUnit;
00302
00303 bool print_assert(const Node *n, const DCUnit *u=0);
00304 bool print_assert_nodes(std::deque<Node *> &nodes, uint32 index);
00305
00306 #endif
00307