Passo intermediario, ainda falta um longo caminho
[pspdecompiler.git] / dataflow.c
blob3381d17d4292e3ca9911147c5d91d945b203cd8f
2 #include "code.h"
3 #include "utils.h"
5 const uint32 regmask_localvars[NUM_REGMASK] = { 0x43FFFFFE, 0x00000000 };
7 static
8 void mark_ssavar (struct ssavar *var, enum ssavartype type, int num)
10 element useel, phiel;
11 struct value *val;
13 var->info = num;
14 var->type = type;
15 useel = list_head (var->uses);
16 while (useel) {
17 struct operation *use = element_getvalue (useel);
18 if (use->type == OP_PHI) {
19 phiel = list_head (use->operands);
20 while (phiel) {
21 struct value *val = element_getvalue (phiel);
22 if (val->val.variable->type == SSAVAR_UNK) {
23 mark_ssavar (val->val.variable, type, num);
25 phiel = element_next (phiel);
27 val = list_headvalue (use->results);
28 if (val->val.variable->type == SSAVAR_UNK)
29 mark_ssavar (val->val.variable, type, num);
31 useel = element_next (useel);
34 if (var->def->type == OP_PHI) {
35 phiel = list_head (var->def->operands);
36 while (phiel) {
37 struct value *val = element_getvalue (phiel);
38 if (val->val.variable->type == SSAVAR_UNK) {
39 mark_ssavar (val->val.variable, type, num);
41 phiel = element_next (phiel);
46 void extract_variables (struct subroutine *sub)
48 element varel;
49 int count = 0;
51 varel = list_head (sub->ssavars);
52 while (varel) {
53 struct ssavar *var = element_getvalue (varel);
54 if (var->type == SSAVAR_UNK) {
55 if (IS_BIT_SET (regmask_localvars, var->name.val.intval)) {
56 if (var->def->type == OP_START) {
57 mark_ssavar (var, SSAVAR_ARGUMENT, var->name.val.intval);
58 } else if (var->def->type == OP_CALL && var->name.val.intval != REGISTER_GPR_V0 &&
59 var->name.val.intval != REGISTER_GPR_V1) {
60 var->type = SSAVAR_INVALID;
61 } else {
62 int istemp = FALSE;
64 if (list_size (var->uses) <= 1) {
65 struct operation *op = list_headvalue (var->uses);
66 if (op) {
67 if (op->type != OP_PHI)
68 istemp = TRUE;
69 } else {
70 istemp = TRUE;
74 if (var->def->type == OP_MOVE || var->def->type == OP_INSTRUCTION) {
75 if (var->def->type == OP_INSTRUCTION) {
76 if (var->def->info.iop.loc->insn->flags & (INSN_LOAD | INSN_STORE | INSN_BRANCH))
77 istemp = FALSE;
79 } else {
80 istemp = FALSE;
83 if (istemp) {
84 var->def->status |= OPERATION_DEFERRED;
85 var->type = SSAVAR_TEMP;
86 var->info = 0;
87 } else {
88 mark_ssavar (var, SSAVAR_LOCAL, ++count);
91 } else {
92 var->type = SSAVAR_ARGUMENT;
95 varel = element_next (varel);