Pristine Ack-5.5
[Ack-5.5.git] / lang / cem / cemcom / util.c
1 /*
2  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
3  * See the copyright notice in the ACK home directory, in the file "Copyright".
4  */
5
6 /* M I S C E L L A N E O U S   U T I L I T I E S */
7
8 /* $Id: util.c,v 3.11 1994/06/24 12:06:47 ceriel Exp $ */
9
10 /*      Code for the allocation and de-allocation of temporary variables,
11         allowing re-use.
12 */
13
14 #include        "lint.h"
15 #ifndef LINT
16 #include        <em.h>
17 #else
18 #include        "l_em.h"
19 #endif  /* LINT */
20 #include        <em_arith.h>
21 #include        <em_reg.h>
22 #include        <alloc.h>
23 #include        <em_mes.h>
24
25 #include        "util.h"
26 #include        "use_tmp.h"
27 #include        "regcount.h"
28 #include        "sizes.h"
29 #include        "align.h"
30 #include        "stack.h"
31 #include        "Lpars.h"
32 #include        "def.h"
33
34 static struct localvar  *FreeTmps;
35 #ifdef USE_TMP
36 static int      loc_id;
37 #endif /* USE_TMP */
38
39 #ifdef PEEPHOLE
40 #undef REGCOUNT
41 #define REGCOUNT 1
42 #endif
43
44 extern char options[];
45
46 LocalInit()
47 {
48 #ifdef USE_TMP
49         C_insertpart(loc_id = C_getid());
50 #endif /* USE_TMP */
51 }
52
53 arith
54 LocalSpace(sz, al)
55         arith sz;
56 {
57         register struct stack_level *stl = local_level;
58
59         stl->sl_max_block = - align(sz - stl->sl_max_block, al);
60         return stl->sl_max_block;
61 }
62
63 #define TABSIZ 32
64 static struct localvar *regs[TABSIZ];
65
66 arith
67 NewLocal(sz, al, regtype, sc)
68         arith sz;
69 {
70         register struct localvar *tmp = FreeTmps;
71         struct localvar *prev = 0;
72         register int index;
73
74         while (tmp) {
75                 if (tmp->t_align >= al &&
76                     tmp->t_size >= sz &&
77                     tmp->t_sc == sc &&
78                     tmp->t_regtype == regtype) {
79                         if (prev) {
80                                 prev->next = tmp->next;
81                         }
82                         else    FreeTmps = tmp->next;
83                         break;
84                 }
85                 prev = tmp;
86                 tmp = tmp->next;
87         }
88         if (! tmp) {
89                 tmp = new_localvar();
90                 tmp->t_offset = LocalSpace(sz, al);
91                 tmp->t_align = al;
92                 tmp->t_size = sz;
93                 tmp->t_sc = sc;
94                 tmp->t_regtype = regtype;
95                 tmp->t_count = REG_DEFAULT;
96         }
97         index = (int) (tmp->t_offset >> 2) & (TABSIZ - 1);
98         tmp->next = regs[index];
99         regs[index] = tmp;
100         return tmp->t_offset;
101 }
102
103 FreeLocal(off)
104         arith off;
105 {
106         int index = (int) (off >> 2) & (TABSIZ - 1);
107         register struct localvar *tmp = regs[index];
108         struct localvar *prev = 0;
109
110         while (tmp && tmp->t_offset != off) {
111                 prev = tmp;
112                 tmp = tmp->next;
113         }
114         if (tmp) {
115                 if (prev)       prev->next = tmp->next;
116                 else            regs[index] = tmp->next;
117                 tmp->next = FreeTmps;
118                 FreeTmps = tmp;
119         }
120 }
121
122 LocalFinish()
123 {
124         register struct localvar *tmp, *tmp1;
125         register int i;
126
127 #ifdef USE_TMP
128         C_beginpart(loc_id);
129 #endif
130         tmp = FreeTmps;
131         while (tmp) {
132                 tmp1 = tmp;
133                 if (tmp->t_sc == REGISTER) tmp->t_count += REG_BONUS;
134                 if (! options['n'] && tmp->t_regtype >= 0) {
135                         C_ms_reg(tmp->t_offset, tmp->t_size, tmp->t_regtype, tmp->t_count);
136                 }
137                 tmp = tmp->next;
138                 free_localvar(tmp1);
139         }
140         FreeTmps = 0;
141         for (i = 0; i < TABSIZ; i++) {
142                 tmp = regs[i];
143                 while (tmp) {
144                         if (tmp->t_sc == REGISTER) tmp->t_count += REG_BONUS;
145                         tmp1 = tmp;
146                         if (! options['n'] && tmp->t_regtype >= 0) {
147                                 C_ms_reg(tmp->t_offset,
148                                          tmp->t_size,
149                                          tmp->t_regtype,
150                                          tmp->t_count);
151                         }
152                         tmp = tmp->next;
153                         free_localvar(tmp1);
154                 }
155                 regs[i] = 0;
156         }
157         if (! options['n']) {
158                 C_mes_begin(ms_reg);
159                 C_mes_end();
160         }
161 #ifdef USE_TMP
162         C_endpart(loc_id);
163 #endif
164 }
165
166 RegisterAccount(offset, size, regtype, sc)
167         arith offset, size;
168 {
169         register struct localvar *p;
170         int index;
171
172         if (regtype < 0) return;
173
174         p = new_localvar();
175         index = (int) (offset >> 2) & (TABSIZ - 1);
176         p->t_offset = offset;
177         p->t_regtype = regtype;
178         p->t_count = REG_DEFAULT;
179         p->t_sc = sc;
180         p->t_size = size;
181         p->next = regs[index];
182         regs[index] = p;
183 }
184
185 static struct localvar *
186 find_reg(off)
187         arith off;
188 {
189         register struct localvar *p = regs[(int)(off >> 2) & (TABSIZ - 1)];
190
191         while (p && p->t_offset != off) p = p->next;
192         return p;
193 }
194
195 LoadLocal(off, sz)
196         arith off, sz;
197 {
198         register struct localvar *p = find_reg(off);
199
200 #ifdef USE_TMP
201 #ifdef REGCOUNT
202         if (p) p->t_count++;
203 #endif
204 #endif
205         if (sz == word_size) C_lol(off);
206         else if (sz == dword_size) C_ldl(off);
207         else {
208                 if (p) p->t_regtype = -1;
209                 C_lal(off);
210                 C_loi(sz);
211         }
212 }
213
214 StoreLocal(off, sz)
215         arith off, sz;
216 {
217         register struct localvar *p = find_reg(off);
218
219 #ifdef USE_TMP
220 #ifdef REGCOUNT
221         if (p) p->t_count++;
222 #endif
223 #endif
224         if (sz == word_size) C_stl(off);
225         else if (sz == dword_size) C_sdl(off);
226         else {
227                 if (p) p->t_regtype = -1;
228                 C_lal(off);
229                 C_sti(sz);
230         }
231 }
232
233 #ifndef LINT
234 AddrLocal(off)
235         arith off;
236 {
237         register struct localvar *p = find_reg(off);
238
239         if (p) p->t_regtype = -1;
240         C_lal(off);
241 }
242 #endif  /* LINT */