1 /* neatcc register allocation */
8 static int l_sz
[NLOCALS
]; /* size of locals */
9 static int l_nr
[NLOCALS
]; /* # of reads */
10 static int l_nw
[NLOCALS
]; /* # of writes */
11 static int l_na
[NLOCALS
]; /* # of address accesses */
12 static int l_reg
[NLOCALS
]; /* register mapped to locals */
13 static int l_n
; /* # of locals */
15 static int f_argc
; /* number of arguments */
16 static int f_varg
; /* function has variable argument list */
17 static int f_lregs
; /* mask of R_TMPS allocated to locals */
18 static int f_sargs
; /* mask of R_ARGS to be saved */
20 void r_func(int nargs
, int varg
)
27 for (i
= 0; i
< f_argc
; i
++)
29 f_sargs
= f_varg
? R_ARGS
: 0;
30 for (i
= 0; i
< f_argc
&& i
< N_ARGS
; i
++)
31 f_sargs
|= 1 << argregs
[i
];
88 /* sort locals for register allocation based on the number of accesses */
89 static int *sortedlocals(void)
91 static int ord
[NLOCALS
];
93 for (i
= 0; i
< l_n
; i
++) {
94 for (j
= i
- 1; j
>= 0; j
--) {
95 if (l_nr
[i
] + l_nw
[i
] <= l_nw
[ord
[j
]] + l_nr
[ord
[j
]])
104 int r_alloc(int leaf
, int used
)
107 int *ord
= sortedlocals();
111 f_sargs
= f_varg
? R_ARGS
: 0;
112 /* except unused arguments, save all arguments on the stack */
113 for (i
= 0; i
< f_argc
&& i
< N_ARGS
; i
++)
114 if (f_varg
|| l_nr
[i
] + l_nw
[i
] + l_na
[i
])
115 f_sargs
|= 1 << argregs
[i
];
116 /* letting arguments stay in their registers for leaf functions */
117 if (!f_varg
&& leaf
) {
118 for (i
= 0; i
< f_argc
&& i
< N_ARGS
; i
++) {
119 if (l_sz
[i
] > LONGSZ
|| (1 << argregs
[i
]) & used
)
121 if (l_nr
[i
] + l_nw
[i
] && !l_na
[i
]) {
122 l_reg
[i
] = argregs
[i
];
123 f_sargs
&= ~(1 << argregs
[i
]);
124 f_lregs
|= (1 << argregs
[i
]);
129 /* try finding a register for each local */
130 for (i
= 0; i
< l_n
; i
++) {
132 int nmask
= (leaf
? 0 : ~R_SAVED
) | used
| f_lregs
;
133 if (l_reg
[l
] >= 0 || (f_varg
&& l
< f_argc
))
135 /* find a free register */
136 while (idx
< N_TMPS
&& ((1 << tmpregs
[idx
]) & nmask
))
140 if (l_sz
[l
] > LONGSZ
|| l_na
[l
])
142 if (l_nr
[l
] + l_nw
[l
] > (leaf
? 0 : 1)) {
143 l_reg
[l
] = tmpregs
[idx
];
144 f_lregs
|= 1 << tmpregs
[idx
];
145 if (l
< N_ARGS
&& l
< f_argc
)
146 f_sargs
&= ~(1 << argregs
[l
]);