Ficando cada vez melhor
[pspdecompiler.git] / analyser.c
blob8f27c7c755ff6b90b0d51beab73fc664308d6c6a
2 #include <stdlib.h>
3 #include <string.h>
5 #include "code.h"
6 #include "utils.h"
8 static
9 struct code *code_alloc (void)
11 struct code *c;
12 c = (struct code *) xmalloc (sizeof (struct code));
13 memset (c, 0, sizeof (struct code));
15 c->lstpool = listpool_create (8192, 4096);
16 c->switchpool = fixedpool_create (sizeof (struct codeswitch), 64, TRUE);
17 c->subspool = fixedpool_create (sizeof (struct subroutine), 1024, TRUE);
18 c->blockspool = fixedpool_create (sizeof (struct basicblock), 4096, TRUE);
19 c->edgespool = fixedpool_create (sizeof (struct basicedge), 8192, TRUE);
20 c->varspool = fixedpool_create (sizeof (struct variable), 4096, TRUE);
21 c->opspool = fixedpool_create (sizeof (struct operation), 8192, TRUE);
22 c->valspool = fixedpool_create (sizeof (struct value), 8192, TRUE);
23 c->loopspool = fixedpool_create (sizeof (struct loopstructure), 256, TRUE);
24 c->ifspool = fixedpool_create (sizeof (struct ifstructure), 1024, TRUE);
26 return c;
29 struct code* code_analyse (struct prx *p)
31 struct code *c = code_alloc ();
32 struct subroutine *sub;
33 element el;
35 c->file = p;
37 if (!decode_instructions (c)) {
38 code_free (c);
39 return NULL;
42 extract_switches (c);
43 extract_subroutines (c);
45 live_registers (c);
47 el = list_head (c->subroutines);
48 while (el) {
49 sub = element_getvalue (el);
50 if (!sub->import && !sub->haserror) {
51 cfg_traverse (sub, FALSE);
52 if (!sub->haserror) {
53 sub->status |= SUBROUTINE_CFG_TRAVERSE;
54 cfg_traverse (sub, TRUE);
57 if (!sub->haserror) {
58 sub->status |= SUBROUTINE_CFG_TRAVERSE_REV;
59 fixup_call_arguments (sub);
62 if (!sub->haserror) {
63 sub->status |= SUBROUTINE_FIXUP_CALL_ARGS;
64 build_ssa (sub);
67 if (!sub->haserror) {
68 sub->status |= SUBROUTINE_SSA;
71 el = element_next (el);
74 live_registers_imports (c);
76 el = list_head (c->subroutines);
77 while (el) {
78 sub = element_getvalue (el);
79 if (!sub->import && !sub->haserror) {
80 if (!(sub->status & SUBROUTINE_FIXUP_CALL_ARGS)) {
81 fixup_call_arguments (sub);
82 if (!sub->haserror) {
83 sub->status |= SUBROUTINE_FIXUP_CALL_ARGS;
84 build_ssa (sub);
88 if (!sub->haserror) {
89 sub->status |= SUBROUTINE_SSA;
90 propagate_constants (sub);
93 if (!sub->haserror) {
94 sub->status |= SUBROUTINE_CONSTANTS_EXTRACTED;
95 extract_variables (sub);
98 if (!sub->haserror) {
99 sub->status |= SUBROUTINE_VARIABLES_EXTRACTED;
100 extract_structures (sub);
103 if (!sub->haserror) {
104 sub->status |= SUBROUTINE_STRUCTURES_EXTRACTED;
107 el = element_next (el);
110 return c;
113 void code_free (struct code *c)
115 if (c->base)
116 free (c->base);
117 c->base = NULL;
119 if (c->lstpool)
120 listpool_destroy (c->lstpool);
121 c->lstpool = NULL;
123 if (c->subspool)
124 fixedpool_destroy (c->subspool, NULL, NULL);
125 c->subspool = NULL;
127 if (c->switchpool)
128 fixedpool_destroy (c->switchpool, NULL, NULL);
129 c->switchpool = NULL;
131 if (c->blockspool)
132 fixedpool_destroy (c->blockspool, NULL, NULL);
133 c->blockspool = NULL;
135 if (c->edgespool)
136 fixedpool_destroy (c->edgespool, NULL, NULL);
137 c->edgespool = NULL;
139 if (c->varspool)
140 fixedpool_destroy (c->varspool, NULL, NULL);
141 c->varspool = NULL;
143 if (c->opspool)
144 fixedpool_destroy (c->opspool, NULL, NULL);
145 c->opspool = NULL;
147 if (c->valspool)
148 fixedpool_destroy (c->valspool, NULL, NULL);
149 c->valspool = NULL;
151 if (c->loopspool)
152 fixedpool_destroy (c->loopspool, NULL, NULL);
153 c->loopspool = NULL;
155 if (c->ifspool)
156 fixedpool_destroy (c->ifspool, NULL, NULL);
157 c->ifspool = NULL;
159 free (c);