7 static int l_sz
[NLOCALS
]; /* size of locals */
8 static int l_nr
[NLOCALS
]; /* # of reads */
9 static int l_nw
[NLOCALS
]; /* # of writes */
10 static int l_na
[NLOCALS
]; /* # of address accesses */
11 static int l_reg
[NLOCALS
]; /* register mapped to locals */
12 static int l_n
; /* # of locals */
14 static int f_argc
; /* number of arguments */
15 static int f_varg
; /* function has variable argument list */
16 static int f_lregs
; /* mask of R_TMPS allocated to locals */
17 static int f_sargs
; /* mask of R_ARGS to be saved */
19 void r_func(int nargs
, int varg
)
26 for (i
= 0; i
< f_argc
; i
++)
28 f_sargs
= f_varg
? R_ARGS
: 0;
29 for (i
= 0; i
< f_argc
&& i
< N_ARGS
; i
++)
30 f_sargs
|= 1 << argregs
[i
];
87 /* sort locals for register allocation based on the number of accesses */
88 static int *sortedlocals(void)
90 static int ord
[NLOCALS
];
92 for (i
= 0; i
< l_n
; i
++) {
93 for (j
= i
- 1; j
>= 0; j
--) {
94 if (l_nr
[i
] + l_nw
[i
] <= l_nw
[ord
[j
]] + l_nr
[ord
[j
]])
103 int r_alloc(int leaf
, int used
)
106 int *ord
= sortedlocals();
110 f_sargs
= f_varg
? R_ARGS
: 0;
111 /* except unused arguments, save all arguments on the stack */
112 for (i
= 0; i
< f_argc
&& i
< N_ARGS
; i
++)
113 if (f_varg
|| l_nr
[i
] + l_nw
[i
] + l_na
[i
])
114 f_sargs
|= 1 << argregs
[i
];
115 /* letting arguments stay in their registers for leaf functions */
116 if (!f_varg
&& leaf
) {
117 for (i
= 0; i
< f_argc
&& i
< N_ARGS
; i
++) {
118 if (l_sz
[i
] > LONGSZ
|| (1 << argregs
[i
]) & used
)
120 if (l_nr
[i
] + l_nw
[i
] && !l_na
[i
]) {
121 l_reg
[i
] = argregs
[i
];
122 f_sargs
&= ~(1 << argregs
[i
]);
123 f_lregs
|= (1 << argregs
[i
]);
128 /* try finding a register for each local */
129 for (i
= 0; i
< l_n
; i
++) {
131 int nmask
= (leaf
? 0 : ~R_SAVED
) | used
| f_lregs
;
132 if (l_reg
[l
] >= 0 || (f_varg
&& l
< f_argc
))
134 /* find a free register */
135 while (idx
< N_TMPS
&& ((1 << tmpregs
[idx
]) & nmask
))
139 if (l_sz
[l
] > LONGSZ
|| l_na
[l
])
141 if (l_nr
[l
] + l_nw
[l
] > (leaf
? 0 : 1)) {
142 l_reg
[l
] = tmpregs
[idx
];
143 f_lregs
|= 1 << tmpregs
[idx
];
144 if (l
< N_ARGS
&& l
< f_argc
)
145 f_sargs
&= ~(1 << argregs
[l
]);