Passo intermediario, ainda falta um longo caminho
[pspdecompiler.git] / analyser.c
blob445c90ab8e9b6dd12c3e6385314d10ea01e3ac52
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->ssavarspool = fixedpool_create (sizeof (struct ssavar), 4096, TRUE);
21 c->opspool = fixedpool_create (sizeof (struct operation), 8192, TRUE);
22 c->valspool = fixedpool_create (sizeof (struct value), 8192, TRUE);
23 c->ctrlspool = fixedpool_create (sizeof (struct ctrlstruct), 256, TRUE);
25 return c;
28 struct code* code_analyse (struct prx *p)
30 struct code *c = code_alloc ();
31 struct subroutine *sub;
32 element el;
34 c->file = p;
36 if (!decode_instructions (c)) {
37 code_free (c);
38 return NULL;
41 extract_switches (c);
42 extract_subroutines (c);
44 live_registers (c);
46 el = list_head (c->subroutines);
47 while (el) {
48 sub = element_getvalue (el);
49 if (!sub->import && !sub->haserror) {
50 cfg_traverse (sub, FALSE);
51 if (!sub->haserror) {
52 sub->status |= SUBROUTINE_CFG_TRAVERSE;
53 cfg_traverse (sub, TRUE);
56 if (!sub->haserror) {
57 sub->status |= SUBROUTINE_CFG_TRAVERSE_REV;
58 fixup_call_arguments (sub);
61 if (!sub->haserror) {
62 sub->status |= SUBROUTINE_FIXUP_CALL_ARGS;
63 build_ssa (sub);
66 if (!sub->haserror) {
67 sub->status |= SUBROUTINE_SSA;
70 el = element_next (el);
73 live_registers_imports (c);
75 el = list_head (c->subroutines);
76 while (el) {
77 sub = element_getvalue (el);
78 if (!sub->import && !sub->haserror) {
79 if (!(sub->status & SUBROUTINE_FIXUP_CALL_ARGS)) {
80 fixup_call_arguments (sub);
81 if (!sub->haserror) {
82 sub->status |= SUBROUTINE_FIXUP_CALL_ARGS;
83 build_ssa (sub);
87 if (!sub->haserror) {
88 sub->status |= SUBROUTINE_SSA;
89 propagate_constants (sub);
92 if (!sub->haserror) {
93 sub->status |= SUBROUTINE_CONSTANTS_EXTRACTED;
94 extract_variables (sub);
97 if (!sub->haserror) {
98 sub->status |= SUBROUTINE_VARIABLES_EXTRACTED;
99 extract_structures (sub);
102 if (!sub->haserror) {
103 sub->status |= SUBROUTINE_STRUCTURES_EXTRACTED;
106 el = element_next (el);
109 return c;
112 void code_free (struct code *c)
114 if (c->base)
115 free (c->base);
116 c->base = NULL;
118 if (c->lstpool)
119 listpool_destroy (c->lstpool);
120 c->lstpool = NULL;
122 if (c->subspool)
123 fixedpool_destroy (c->subspool, NULL, NULL);
124 c->subspool = NULL;
126 if (c->switchpool)
127 fixedpool_destroy (c->switchpool, NULL, NULL);
128 c->switchpool = NULL;
130 if (c->blockspool)
131 fixedpool_destroy (c->blockspool, NULL, NULL);
132 c->blockspool = NULL;
134 if (c->edgespool)
135 fixedpool_destroy (c->edgespool, NULL, NULL);
136 c->edgespool = NULL;
138 if (c->ssavarspool)
139 fixedpool_destroy (c->ssavarspool, NULL, NULL);
140 c->ssavarspool = NULL;
142 if (c->opspool)
143 fixedpool_destroy (c->opspool, NULL, NULL);
144 c->opspool = NULL;
146 if (c->valspool)
147 fixedpool_destroy (c->valspool, NULL, NULL);
148 c->valspool = NULL;
150 if (c->ctrlspool)
151 fixedpool_destroy (c->ctrlspool, NULL, NULL);
152 c->ctrlspool = NULL;
154 free (c);