1 /* catch register messages. BEWARE: code uses plain printf's (fprint's)
2 * to generate code. This is not compatible with the usual procedure
15 #define MAX_NR_REGS 12
16 #define MAX_NR_FLTS MAX_NR_FLT_REGS /* depends on using float or doubles */
23 typedef struct reg_info {
25 int size; /* 4 or 8 */
27 reg_t reg, reg2; /* reg2 used for doubles only */
30 static reg_info reg_dat[MAX_NR_REGS], flt_dat[MAX_NR_FLTS];
32 static int current_reg_mes[RM_COUNT+4];
34 static int in_reg_mes = 0; /* boolean */
35 static int reg_mes_nr;
36 static int db_mes = 0;
37 static int db_kind = 0;
38 static int db_str = 0;
39 static int db_nul = 0; /* boolean */
41 static int worst_reg_pri, worst_flt_pri; /* reset by C_prolog (to some large number) */
42 static int nr_reg_vars, nr_flt_vars; /* dito (both to 0) */
46 worst_reg_pri = worst_flt_pri = (unsigned)-1/2;
47 nr_reg_vars = nr_flt_vars = 0;
50 static reg_t my_alloc_reg(pri,loc)
56 if ((S1 = alloc_reg_var()) == NULL)
57 if (current_reg_mes[RM_COUNT] > worst_reg_pri) {
58 for (i = 0; i < nr_reg_vars; i++)
59 if (reg_dat[i].pri <= worst_reg_pri) {
64 worst_reg_pri = (unsigned)-1/2;
65 for (i = 0; i < nr_reg_vars; i++)
66 if (reg_dat[i].pri <= worst_reg_pri)
67 worst_reg_pri = reg_dat[i].pri;
69 return NULL; /* SORRY, FULL HOUSE! */
76 static reg_t my_alloc_double(pri,loc,r2)
79 /* implementation note: my_alloc_double only reclaims other doubles
80 * when a better candidate is given. It never reclaims floats, even if
81 * the current double is a mich better candidate.
87 if ((S1 = alloc_double_var(r2)) == NULL)
88 if (current_reg_mes[RM_COUNT] > worst_flt_pri) {
89 for (i = 0; i < nr_flt_vars; i++)
90 if (flt_dat[i].pri <= worst_flt_pri &&
91 flt_dat[i].size == EM_DSIZE) {
94 *r2 = flt_dat[i].reg2;
97 worst_flt_pri = (unsigned)-1/2;
98 for (i = 0; i < nr_flt_vars; i++)
99 if (flt_dat[i].pri < worst_flt_pri)
100 worst_flt_pri = flt_dat[i].pri;
102 return NULL; /* SORRY, FULL HOUSE! */
104 *loc = nr_flt_vars++;
109 static reg_t my_alloc_float(pri,loc)
111 /* just as for my_alloc_double, my_alloc_float never reclaims a double,
112 * even though this me be useful and easy. Sorry.
118 if ((S1 = alloc_float_var()) == NULL)
119 if (current_reg_mes[RM_COUNT] > worst_flt_pri) {
120 for (i = 0; i < nr_flt_vars; i++)
121 if (flt_dat[i].pri <= worst_flt_pri &&
122 flt_dat[i].size == EM_WSIZE) {
127 worst_flt_pri = (unsigned)-1/2;
128 for (i = 0; i < nr_flt_vars; i++)
129 if (flt_dat[i].pri <= worst_flt_pri)
130 worst_flt_pri = flt_dat[i].pri;
132 return NULL; /* SORRY, FULL HOUSE! */
134 *loc = nr_flt_vars++;
143 for (i = 0; i < nr_reg_vars; i++)
144 free_reg(reg_dat[i].reg);
145 for (i = 0; i < nr_flt_vars; i++)
146 switch (flt_dat[i].size) {
147 case EM_WSIZE: free_reg(flt_dat[i].reg); break;
148 case EM_DSIZE: free_double_reg(flt_dat[i].reg); break;
157 for (i = 0; i < nr_reg_vars; i++)
158 forced_alloc_reg(reg_dat[i].reg);
159 for (i = 0; i < nr_flt_vars; i++)
160 switch (flt_dat[i].size) {
161 case EM_WSIZE: forced_alloc_reg(flt_dat[i].reg); break;
163 forced_alloc_reg(flt_dat[i].reg);
164 forced_alloc_reg(flt_dat[i].reg2);
170 static params_to_regs() /* copy required parameters to registers */
174 for (i = 0; i < nr_flt_vars; i++)
175 if (flt_dat[i].offset >= 4092) {
176 fprint(codefile, "set %d, %%l2\n",
178 fprint(codefile, "ld [%%l1+%%l2], %s\n",
180 if (flt_dat[i].size == EM_DSIZE) {
181 fprint(codefile, "set %d, %%l2\n",
182 flt_dat[i].offset+4);
183 fprint(codefile, "ld [%%l1+%%l2], %s\n",
187 else if (flt_dat[i].offset > 0)
189 fprint(codefile, "ld [%%l1+%d], %s\n",
190 flt_dat[i].offset, flt_dat[i].reg);
191 if (flt_dat[i].size == EM_DSIZE)
192 fprint(codefile, "ld [%%l1+%d], %s\n",
193 flt_dat[i].offset + 4, flt_dat[i].reg2);
196 for (i = 0; i < nr_reg_vars; i++)
197 if (reg_dat[i].offset >= 4096) {
198 fprint(codefile, "set %d, %s\n",
199 reg_dat[i].offset, reg_dat[i].reg);
200 fprint(codefile, "ld [%%l1+%s], %s\n",
201 reg_dat[i].reg, reg_dat[i].reg);
203 else if (reg_dat[i].offset > 0)
204 fprint(codefile, "ld [%%l1+%d], %s\n",
205 reg_dat[i].offset, reg_dat[i].reg);
208 static cmp_flt_dat(e1, e2)
211 return (e1->offset - e2->offset);
218 /* Assume ASCII, where even-numbered characters (0,2,4,6,8) are even. */
219 return ! (s[l-1] & 1);
222 static save_float_regs()
227 qsort(flt_dat, nr_flt_vars, sizeof(flt_dat[0]), cmp_flt_dat);
228 for (i = 0, offset= 0; i < nr_flt_vars; i++, offset += 8)
229 if ((i+1 < nr_flt_vars &&
230 flt_dat[i].offset == flt_dat[i+1].offset-4 &&
231 even(flt_dat[i].reg) &&
232 flt_dat[i].size == EM_FSIZE &&
233 flt_dat[i+1].size == EM_FSIZE)
234 || (flt_dat[i].size == EM_DSIZE)) {
235 fprint(codefile, "std %s, [%%fp + %d]\n",
236 flt_dat[i].reg, FLTSAV_OFFSET + offset);
237 if (flt_dat[i].size != EM_DSIZE)
240 fprint(codefile, "st %s, [%%fp + %d]\n",
241 flt_dat[i].reg, FLTSAV_OFFSET + offset);
249 for (i = 0, offset= 0; i < nr_flt_vars; i++, offset += 8)
250 if ((i+1 < nr_flt_vars &&
251 flt_dat[i].offset == flt_dat[i+1].offset-4 &&
252 even(flt_dat[i].reg) &&
253 flt_dat[i].size == EM_FSIZE &&
254 flt_dat[i+1].size == EM_FSIZE)
255 || (flt_dat[i].size == EM_DSIZE)) {
256 fprint(codefile, "ldd [%%fp + %d], %s\n",
257 FLTSAV_OFFSET + offset, flt_dat[i].reg);
258 if (flt_dat[i].size != EM_DSIZE)
261 fprint(codefile, "ld [%%fp + %d], %s\n",
262 FLTSAV_OFFSET + offset, flt_dat[i].reg);
275 in_reg_mes = (ms == ms_reg);
278 nr_reg_vars = 0; nr_flt_vars = 0;
279 fprint(codefile, "ta 3\n");
281 db_mes = (ms == ms_stb || ms == ms_std) ? ms : 0;
283 if (db_mes && ! inits) {
284 fprint(codefile, ".pushsection \".text\"\nBtext.text:\n.popsection\n");
285 fprint(codefile, ".pushsection \".data\"\nBdata.data:\n.popsection\n");
286 fprint(codefile, ".pushsection \".bss\"\nBbss.bss:\n.popsection\n");
292 static dump_reg_tabs();
295 extern char *B_procnam;
307 if (db_mes == ms_std) {
309 fprint(codefile, ",1f\n1:\n");
312 fprint(codefile, ",1f-%s\n1:\n", B_procnam);
316 if (db_mes == ms_std && db_str == 2) fprint(codefile,",1f\n1:\n");
318 else fprint(codefile, "\n");
323 if (!in_reg_mes) /* end of some other mes */
325 if (reg_mes_nr == 0) { /* end of reg_mes's */
329 dump_reg_tabs(codefile);
332 if (current_reg_mes[RM_COUNT] == 0) /* never used, so ignore */
334 if (current_reg_mes[RM_OFFSET] >= 0)
335 current_reg_mes[RM_OFFSET] += EM_BSIZE;
337 fprint(codefile, "\t\t! Got reg_mes: %d %d %d %d\n",
338 current_reg_mes[0], current_reg_mes[1],
339 current_reg_mes[2], current_reg_mes[3]);
340 if (current_reg_mes[RM_TYPE] == reg_float) {
341 switch(current_reg_mes[RM_SIZE]) {
343 if ((S1 = my_alloc_float(current_reg_mes[RM_COUNT], &pos))
348 if ((S1 = my_alloc_double(current_reg_mes[RM_COUNT], &pos, &S2))
351 flt_dat[pos].reg2 = S2;
354 flt_dat[pos].offset = current_reg_mes[RM_OFFSET];
355 flt_dat[pos].size = current_reg_mes[RM_SIZE];
356 flt_dat[pos].pri = current_reg_mes[RM_COUNT];
357 flt_dat[pos].reg = S1;
359 if (current_reg_mes[RM_SIZE] != EM_WSIZE)
360 return; /* IGNORE THESE */
361 if ((S1 = my_alloc_reg(current_reg_mes[RM_COUNT], &pos)) == NULL)
362 return; /* SORRY, FULL HOUSE! */
364 reg_dat[pos].offset = current_reg_mes[RM_OFFSET];
365 reg_dat[pos].size = current_reg_mes[RM_SIZE];
366 reg_dat[pos].pri = current_reg_mes[RM_COUNT];
367 reg_dat[pos].reg = S1;
371 extern int __gdb_flag;
377 static int correct_offset;
380 if (! db_kind) db_kind = l;
383 if (l == N_SLINE && ! __gdb_flag) {
386 fprint(codefile, "call $__uX_LiB\nnop\n");
388 fprint(codefile, "call ___uX_LiB\nnop\n");
392 fprint(codefile, ".stabn 0x%lx,0", (long) l);
394 if (db_mes == ms_std) {
395 fprint(codefile, ".stabd 0x%lx,0", (long) l);
397 else fprint(codefile, ".stabn 0x%lx,0", (long) l);
403 if (correct_offset++ == -1) {
406 fprint(codefile, ",0x%lx", (long) l);
410 if (l == N_PSYM && __gdb_flag) {
413 fprint(codefile, ",0");
418 current_reg_mes[reg_mes_nr++] = l;
427 fprint(codefile, ".stabs \"");
429 register int c = *s++;
431 if (isprint(c) && c != '"' && c != '\\')
432 fprint(codefile, "%c", c);
434 fprint(codefile, "\\%03o", c);
436 fprint(codefile, "\"");
447 fprint(codefile,",");
448 fprint(codefile, DLB_FMT, (long) l);
449 if (off) fprint(codefile,"+%ld", (long) off);
453 fprint(codefile, "-Bbss.bss");
456 fprint(codefile, "-Bdata.data");
469 fprint(codefile,",");
470 fprint(codefile, DNAM_FMT, l);
471 if (off) fprint(codefile,"+%ld", (long) off);
475 fprint(codefile, "-Bbss.bss");
478 fprint(codefile, "-Bdata.data");
492 fprint(codefile,",");
493 fprint(codefile, ILB_FMT, B_procno, (long)l);
495 fprint(codefile, "-Btext.text");
505 fprint(codefile,",");
506 fprint(codefile, NAME_FMT, s);
508 fprint(codefile, "-Btext.text");
514 dump_reg_tabs(stream)
519 fprint(stream, "!offset\tsize\tname (%d regvars)\n", nr_reg_vars);
520 for (i = 0; i < nr_reg_vars; i++)
521 fprint(stream, "! %d\t%d\t%s\n", reg_dat[i].offset, reg_dat[i].size,
524 fprint(stream, "!offset\tsize\tname (%d fltvars)\n", nr_flt_vars);
525 for (i = 0; i < nr_flt_vars; i++)
526 fprint(stream, "! %d\t%d\t%s\n", flt_dat[i].offset, flt_dat[i].size,
530 reg_t find_local(offset, reg2) /* WARNING: no size checking here! */
538 for (i = 0; i < nr_reg_vars; i++)
539 if (reg_dat[i].offset == offset)
540 return reg_dat[i].reg;
542 for (i = 0; i < nr_flt_vars; i++)
543 if (flt_dat[i].offset == offset) {
544 if (flt_dat[i].size == EM_DSIZE)
546 *reg2 = flt_dat[i].reg2;
547 return flt_dat[i].reg;