Com o autor
[pspdecompiler.git] / dataflow.c
blob9551d48690abffebb413de8ae089bde49d3f6394
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 if (var->type == SSAVAR_UNK) {
58 if (IS_BIT_SET (regmask_localvars, var->name.val.intval)) {
59 if (var->def->type == OP_START) {
60 mark_ssavar (var, SSAVAR_ARGUMENT, var->name.val.intval);
61 } else if (var->def->type == OP_CALL && var->name.val.intval != REGISTER_GPR_V0 &&
62 var->name.val.intval != REGISTER_GPR_V1) {
63 var->type = SSAVAR_INVALID;
64 } else {
65 int istemp = FALSE;
67 if (list_size (var->uses) <= 1) {
68 struct operation *op = list_headvalue (var->uses);
69 if (op) {
70 if (op->type != OP_PHI)
71 istemp = TRUE;
72 } else {
73 istemp = TRUE;
77 if (var->def->type == OP_MOVE || var->def->type == OP_INSTRUCTION) {
78 if (var->def->type == OP_INSTRUCTION) {
79 if (var->def->info.iop.loc->insn->flags & (INSN_LOAD | INSN_STORE | INSN_BRANCH))
80 istemp = FALSE;
82 } else {
83 istemp = FALSE;
86 if (istemp) {
87 var->def->status |= OP_STAT_DEFERRED;
88 var->type = SSAVAR_TEMP;
89 var->info = 0;
90 } else {
91 mark_ssavar (var, SSAVAR_LOCAL, ++count);
94 } else {
95 var->type = SSAVAR_ARGUMENT;
98 varel = element_next (varel);