2 * Author: Humberto Naves (hsnaves@gmail.com)
8 const uint32 regmask_localvars
[NUM_REGMASK
] = { 0x43FFFFFE, 0x00000003 };
11 void mark_ssavar (struct ssavar
*var
, enum ssavartype type
, int num
)
18 useel
= list_head (var
->uses
);
20 struct operation
*use
= element_getvalue (useel
);
21 if (use
->type
== OP_PHI
) {
22 phiel
= list_head (use
->operands
);
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
);
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
)
54 varel
= list_head (sub
->ssavars
);
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);
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
;
88 mark_ssavar (var
, SSAVAR_LOCAL
, ++count
);
92 mark_ssavar (var
, SSAVAR_ARGUMENT
, var
->name
.val
.intval
);
95 varel
= element_next (varel
);