SLLV, SRLV, SRAV and ROTV have reverse order of operands
[pspdecompiler.git] / dataflow.c
blobfb7dab44508092f1397d3b334777a83065ae7c5d
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, 0x00000003 };
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;
75 if (op->type == OP_INSTRUCTION) {
76 if (op->info.iop.loc->insn->flags & (INSN_LOAD | INSN_STORE))
77 op->status &= ~OP_STAT_DEFERRED;
78 else if ((op->info.iop.loc->insn->flags & (INSN_BRANCH)) &&
79 !op->info.iop.loc->branchalways)
80 op->status &= ~OP_STAT_DEFERRED;
84 if (op->status & OP_STAT_DEFERRED) {
85 var->type = SSAVAR_TEMP;
86 var->info = 0;
87 } else {
88 mark_ssavar (var, SSAVAR_LOCAL, ++count);
91 } else {
92 mark_ssavar (var, SSAVAR_ARGUMENT, var->name.val.intval);
95 varel = element_next (varel);