00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef CALLNODES_H
00022 #define CALLNODES_H
00023
00024 #include "GenericNodes.h"
00025
00026 #include <list>
00027
00028 class DCCallPostfixNode : public Node
00029 {
00030 public:
00031 DCCallPostfixNode() : Node() {};
00032 DCCallPostfixNode(const uint32 opcode, const uint32 offset, const uint32 newSP)
00033 : Node(opcode, offset, Type(Type::T_INVALID)), sp(newSP)
00034 {
00035 assert(acceptOp(opcode, 0x65, 0x6E));
00036 switch(opcode)
00037 {
00038 case 0x65: ptype=FREESTR; break;
00039 case 0x6E: ptype=ADDSP; break;
00040 default: assert(false);
00041 }
00042 };
00043 DCCallPostfixNode(const uint32 opcode, const uint32 offset)
00044 : Node(opcode, offset, Type(Type::T_INVALID)), sp(0)
00045 {
00046 assert(acceptOp(opcode, 0x5D, 0x5E));
00047 switch(opcode)
00048 {
00049 case 0x5D: ptype=PUSH_RETVAL; rtype(Type::T_BYTE); break;
00050 case 0x5E: ptype=PUSH_RETVAL; rtype(Type::T_WORD); break;
00051 default: assert(false);
00052 }
00053 };
00054 ~DCCallPostfixNode() {};
00055
00056 void print() const {};
00057 void print_unk(Console &o, const uint32 isize, const bool comment) const;
00058 void print_unk(Console &o, const uint32 isize) const { print_unk(o, isize, true); };
00059 void print_asm(Console &o) const;
00060 void print_bin(ODequeDataSource &o) const;
00061
00062 bool fold(DCUnit *unit, std::deque<Node *> &nodes);
00063
00064 sint32 size() const { return static_cast<sint8>(sp); };
00065
00066 protected:
00067 enum callpostfixtype { PUSH_RETVAL, FREESTR, ADDSP } ptype;
00068
00069 private:
00070 uint32 sp;
00071 };
00072
00073 class DCCallMutatorNode : public BinNode
00074 {
00075 public:
00076 DCCallMutatorNode(const uint32 opcode, const uint32 offset, const uint32 newNumBytes)
00077 : BinNode(opcode, offset, Type(Type::T_INVALID)), numBytes(newNumBytes)
00078 {
00079 assert(acceptOp(opcode, 0x4C));
00080 mtype=PUSH_INDIRECT;
00081 switch(numBytes)
00082 {
00083 case 2: rtype(Type::T_WORD); break;
00084 default: assert(false);
00085 }
00086 };
00087 DCCallMutatorNode(const uint32 opcode, const uint32 offset)
00088 : BinNode(opcode, offset, Type(Type::T_INVALID)), numBytes(0)
00089 {
00090 assert(acceptOp(opcode, 0x77, 0x78));
00091 switch(opcode)
00092 {
00093 case 0x77: mtype=SET_INFO; break;
00094 case 0x78: mtype=PROCESS_EXCLUDE; break;
00095 default: assert(false);
00096 }
00097 };
00098 ~DCCallMutatorNode() {};
00099
00100 void print_unk(Console &o, const uint32 isize, const bool comment) const;
00101 void print_unk(Console &o, const uint32 isize) const { print_unk(o, isize, true); };
00102 void print_asm(Console &o) const;
00103 void print_bin(ODequeDataSource &o) const;
00104
00105 bool fold(DCUnit *unit, std::deque<Node *> &nodes);
00106
00107 protected:
00108 enum mutatortype { PUSH_INDIRECT, SET_INFO, PROCESS_EXCLUDE } mtype;
00109
00110 private:
00111 uint32 numBytes;
00112
00113 public:
00114 const Node *a_lnode() const { return lnode; };
00115 const Node *a_rnode() const { return rnode; };
00116 };
00117
00118 class DCCallNode : public ColNode
00119 {
00120 public:
00121 DCCallNode() : ColNode() {};
00122 DCCallNode(const uint32 opcode, const uint32 offset, const uint32 newValue1, const uint32 newValue2)
00123 : ColNode(opcode, offset, Type(Type::T_VOID)), addSP(0), retVal(0), thisP(0)
00124 {
00125 assert(acceptOp(opcode, 0x0F, 0x11));
00126 switch(opcode)
00127 {
00128 case 0x0F:
00129 ctype = CALLI;
00130 spsize = newValue1;
00131 intrinsic = newValue2;
00132 break;
00133 case 0x11:
00134 ctype = CALL;
00135 uclass = newValue1;
00136 targetOffset = newValue2;
00137 break;
00138 default: assert(false);
00139 }
00140 };
00141 DCCallNode(const uint32 opcode, const uint32 offset, const uint32 newValue1, const uint32 newValue2, const uint32 newValue3, const uint32 newValue4)
00142 : ColNode(opcode, offset, Type(Type::T_VOID)), addSP(0), retVal(0), thisP(0)
00143 {
00144 assert(acceptOp(opcode, 0x57));
00145 con.Printf("SPAWN: %04X: %02X %02X %02X\n", opcode, offset, newValue1, newValue2);
00146 switch(opcode)
00147 {
00148 case 0x57:
00149 ctype = SPAWN;
00150 spsize = newValue1;
00151 thispsize = newValue2;
00152 uclass = newValue3;
00153 targetOffset = newValue4;
00154 break;
00155 default: assert(false);
00156 }
00157 };
00158 ~DCCallNode() {};
00159
00160 void print() const {};
00161 void print_extern_unk(Console &o, const uint32 isize) const;
00162 void print_unk(Console &o, const uint32 isize) const;
00163 void print_asm(Console &o) const;
00164 void print_bin(ODequeDataSource &o) const;
00165
00166 bool fold(DCUnit *unit, std::deque<Node *> &nodes);
00167
00168
00169 void setAddSP(DCCallPostfixNode *newAddSP) { addSP = newAddSP; };
00170 void setRetVal(DCCallPostfixNode *newRetVal) { retVal = newRetVal; rtype(retVal->rtype()); };
00171 void addFree(DCCallPostfixNode *newFree) { freenodes.push_back(newFree); };
00172
00173 protected:
00174 enum calltype { CALLI, CALL, SPAWN } ctype;
00175
00176 private:
00177 uint32 uclass;
00178 uint32 targetOffset;
00179
00180 uint32 spsize;
00181 uint32 intrinsic;
00182
00183 uint32 thispsize;
00184
00185 DCCallPostfixNode *addSP;
00186 DCCallPostfixNode *retVal;
00187 Node *thisP;
00188 std::list<DCCallPostfixNode *> freenodes;
00189 };
00190
00191
00192 #endif