SLLV, SRLV, SRAV and ROTV have reverse order of operands
[pspdecompiler.git] / analyser.c
blob499bc080b72c2d325d7b2a3fe20b79e1150e8ebb
1 /**
2 * Author: Humberto Naves (hsnaves@gmail.com)
3 */
5 #include <stdlib.h>
6 #include <string.h>
8 #include "code.h"
9 #include "utils.h"
11 static
12 struct code *code_alloc (void)
14 struct code *c;
15 c = (struct code *) xmalloc (sizeof (struct code));
16 memset (c, 0, sizeof (struct code));
18 c->lstpool = listpool_create (8192, 4096);
19 c->switchpool = fixedpool_create (sizeof (struct codeswitch), 64, TRUE);
20 c->subspool = fixedpool_create (sizeof (struct subroutine), 1024, TRUE);
21 c->blockspool = fixedpool_create (sizeof (struct basicblock), 4096, TRUE);
22 c->edgespool = fixedpool_create (sizeof (struct basicedge), 8192, TRUE);
23 c->ssavarspool = fixedpool_create (sizeof (struct ssavar), 4096, TRUE);
24 c->opspool = fixedpool_create (sizeof (struct operation), 8192, TRUE);
25 c->valspool = fixedpool_create (sizeof (struct value), 8192, TRUE);
26 c->ctrlspool = fixedpool_create (sizeof (struct ctrlstruct), 256, TRUE);
28 return c;
31 struct code* code_analyse (struct prx *p)
33 struct code *c = code_alloc ();
34 struct subroutine *sub;
35 element el;
37 c->file = p;
39 if (!decode_instructions (c)) {
40 code_free (c);
41 return NULL;
44 extract_switches (c);
45 extract_subroutines (c);
47 live_registers (c);
49 el = list_head (c->subroutines);
50 while (el) {
51 sub = element_getvalue (el);
52 if (!sub->import && !sub->haserror) {
53 cfg_traverse (sub, FALSE);
54 if (!sub->haserror) {
55 sub->status |= SUB_STAT_CFG_TRAVERSE;
56 cfg_traverse (sub, TRUE);
59 if (!sub->haserror) {
60 sub->status |= SUB_STAT_CFG_TRAVERSE_REV;
61 fixup_call_arguments (sub);
64 if (!sub->haserror) {
65 sub->status |= SUB_STAT_FIXUP_CALL_ARGS;
66 build_ssa (sub);
69 if (!sub->haserror) {
70 sub->status |= SUB_STAT_SSA;
73 el = element_next (el);
76 live_registers_imports (c);
78 el = list_head (c->subroutines);
79 while (el) {
80 sub = element_getvalue (el);
81 if (!sub->import && !sub->haserror) {
82 if (!(sub->status & SUB_STAT_FIXUP_CALL_ARGS)) {
83 fixup_call_arguments (sub);
84 if (!sub->haserror) {
85 sub->status |= SUB_STAT_FIXUP_CALL_ARGS;
86 build_ssa (sub);
90 if (!sub->haserror) {
91 sub->status |= SUB_STAT_SSA;
92 propagate_constants (sub);
95 if (!sub->haserror) {
96 sub->status |= SUB_STAT_CONSTANTS_EXTRACTED;
97 extract_variables (sub);
100 if (!sub->haserror) {
101 sub->status |= SUB_STAT_VARIABLES_EXTRACTED;
102 extract_structures (sub);
105 if (!sub->haserror) {
106 sub->status |= SUB_STAT_STRUCTURES_EXTRACTED;
109 el = element_next (el);
112 return c;
115 void code_free (struct code *c)
117 if (c->base)
118 free (c->base);
119 c->base = NULL;
121 if (c->lstpool)
122 listpool_destroy (c->lstpool);
123 c->lstpool = NULL;
125 if (c->subspool)
126 fixedpool_destroy (c->subspool, NULL, NULL);
127 c->subspool = NULL;
129 if (c->switchpool)
130 fixedpool_destroy (c->switchpool, NULL, NULL);
131 c->switchpool = NULL;
133 if (c->blockspool)
134 fixedpool_destroy (c->blockspool, NULL, NULL);
135 c->blockspool = NULL;
137 if (c->edgespool)
138 fixedpool_destroy (c->edgespool, NULL, NULL);
139 c->edgespool = NULL;
141 if (c->ssavarspool)
142 fixedpool_destroy (c->ssavarspool, NULL, NULL);
143 c->ssavarspool = NULL;
145 if (c->opspool)
146 fixedpool_destroy (c->opspool, NULL, NULL);
147 c->opspool = NULL;
149 if (c->valspool)
150 fixedpool_destroy (c->valspool, NULL, NULL);
151 c->valspool = NULL;
153 if (c->ctrlspool)
154 fixedpool_destroy (c->ctrlspool, NULL, NULL);
155 c->ctrlspool = NULL;
157 free (c);