Melhorado o structures
[pspdecompiler.git] / dataflow.c
blob6d5f40a107c0faca706fb1cc2fdd408fdf86972f
1 /**
2 * Author: Humberto Naves (hsnaves@gmail.com)
3 */
5 #include "code.h"
6 #include "utils.h"
8 const uint32 regmask_localvars[NUM_REGMASK] = { 0x43FFFFFE, 0x00000000 };
10 static
11 void mark_ssavar (struct ssavar *var, enum ssavartype type, int num)
13 element useel, phiel;
14 struct value *val;
16 var->info = num;
17 var->type = type;
18 useel = list_head (var->uses);
19 while (useel) {
20 struct operation *use = element_getvalue (useel);
21 if (use->type == OP_PHI) {
22 phiel = list_head (use->operands);
23 while (phiel) {
24 struct value *val = element_getvalue (phiel);
25 if (val->val.variable->type == SSAVAR_UNK) {
26 mark_ssavar (val->val.variable, type, num);
28 phiel = element_next (phiel);
30 val = list_headvalue (use->results);
31 if (val->val.variable->type == SSAVAR_UNK)
32 mark_ssavar (val->val.variable, type, num);
34 useel = element_next (useel);
37 if (var->def->type == OP_PHI) {
38 phiel = list_head (var->def->operands);
39 while (phiel) {
40 struct value *val = element_getvalue (phiel);
41 if (val->val.variable->type == SSAVAR_UNK) {
42 mark_ssavar (val->val.variable, type, num);
44 phiel = element_next (phiel);
49 void extract_variables (struct subroutine *sub)
51 element varel;
52 int count = 0;
54 varel = list_head (sub->ssavars);
55 while (varel) {
56 struct ssavar *var = element_getvalue (varel);
57 struct operation *op = var->def;
59 if (var->type == SSAVAR_UNK) {
60 if (IS_BIT_SET (regmask_localvars, var->name.val.intval)) {
61 if (op->type == OP_START) {
62 mark_ssavar (var, SSAVAR_ARGUMENT, var->name.val.intval);
63 } else if (op->type == OP_CALL && var->name.val.intval != REGISTER_GPR_V0 &&
64 var->name.val.intval != REGISTER_GPR_V1) {
65 mark_ssavar (var, SSAVAR_INVALID, 0);
66 } else {
68 if (op->type == OP_MOVE || op->type == OP_INSTRUCTION) {
69 if (!(var->status & (VAR_STAT_PHIARG | VAR_STAT_ASMARG))) {
70 if (list_size (var->uses) <= 1)
71 op->status |= OP_STAT_DEFERRED;
74 if (op->type == OP_INSTRUCTION) {
75 if (op->info.iop.loc->insn->flags & (INSN_LOAD | INSN_STORE))
76 op->status &= ~OP_STAT_DEFERRED;
77 else if ((op->info.iop.loc->insn->flags & (INSN_BRANCH)) &&
78 !op->info.iop.loc->branchalways)
79 op->status &= ~OP_STAT_DEFERRED;
83 if (op->status & OP_STAT_DEFERRED) {
84 var->type = SSAVAR_TEMP;
85 var->info = 0;
86 } else {
87 mark_ssavar (var, SSAVAR_LOCAL, ++count);
90 } else {
91 mark_ssavar (var, SSAVAR_ARGUMENT, var->name.val.intval);
94 varel = element_next (varel);