123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550 |
- /* catch register messages. BEWARE: code uses plain printf's (fprint's)
- * to generate code. This is not compatible with the usual procedure
- * used in the EM_table
- */
- #define CODE_EXPANDER
- #include <em.h>
- #include <em_reg.h>
- #include <em_mes.h>
- #include <stb.h>
- #include "mach.h"
- #include "push_pop.h"
- #include <stdio.h>
- #define MAX_NR_REGS 12
- #define MAX_NR_FLTS MAX_NR_FLT_REGS /* depends on using float or doubles */
- #define RM_OFFSET 0
- #define RM_SIZE 1
- #define RM_TYPE 2
- #define RM_COUNT 3
- typedef struct reg_info {
- int offset;
- int size; /* 4 or 8 */
- int pri;
- reg_t reg, reg2; /* reg2 used for doubles only */
- } reg_info;
- static reg_info reg_dat[MAX_NR_REGS], flt_dat[MAX_NR_FLTS];
- static int current_reg_mes[RM_COUNT+4];
- static int in_reg_mes = 0; /* boolean */
- static int reg_mes_nr;
- static int db_mes = 0;
- static int db_kind = 0;
- static int db_str = 0;
- static int db_nul = 0; /* boolean */
- static int worst_reg_pri, worst_flt_pri; /* reset by C_prolog (to some large number) */
- static int nr_reg_vars, nr_flt_vars; /* dito (both to 0) */
- init_reg_man()
- {
- worst_reg_pri = worst_flt_pri = (unsigned)-1/2;
- nr_reg_vars = nr_flt_vars = 0;
- }
- static reg_t my_alloc_reg(pri,loc)
- int pri, *loc;
- {
- reg_t S1;
- int i;
- if ((S1 = alloc_reg_var()) == NULL)
- if (current_reg_mes[RM_COUNT] > worst_reg_pri) {
- for (i = 0; i < nr_reg_vars; i++)
- if (reg_dat[i].pri <= worst_reg_pri) {
- *loc = i;
- S1 = reg_dat[i].reg;
- break;
- }
- worst_reg_pri = (unsigned)-1/2;
- for (i = 0; i < nr_reg_vars; i++)
- if (reg_dat[i].pri <= worst_reg_pri)
- worst_reg_pri = reg_dat[i].pri;
- } else
- return NULL; /* SORRY, FULL HOUSE! */
- else
- *loc = nr_reg_vars++;
- return S1;
- }
- static reg_t my_alloc_double(pri,loc,r2)
- int pri, *loc;
- reg_t *r2;
- /* implementation note: my_alloc_double only reclaims other doubles
- * when a better candidate is given. It never reclaims floats, even if
- * the current double is a mich better candidate.
- */
- {
- reg_t S1;
- int i;
- if ((S1 = alloc_double_var(r2)) == NULL)
- if (current_reg_mes[RM_COUNT] > worst_flt_pri) {
- for (i = 0; i < nr_flt_vars; i++)
- if (flt_dat[i].pri <= worst_flt_pri &&
- flt_dat[i].size == EM_DSIZE) {
- *loc = i;
- S1 = flt_dat[i].reg;
- *r2 = flt_dat[i].reg2;
- break;
- }
- worst_flt_pri = (unsigned)-1/2;
- for (i = 0; i < nr_flt_vars; i++)
- if (flt_dat[i].pri < worst_flt_pri)
- worst_flt_pri = flt_dat[i].pri;
- } else
- return NULL; /* SORRY, FULL HOUSE! */
- else
- *loc = nr_flt_vars++;
- return S1;
- }
- static reg_t my_alloc_float(pri,loc)
- int pri, *loc;
- /* just as for my_alloc_double, my_alloc_float never reclaims a double,
- * even though this me be useful and easy. Sorry.
- */
- {
- reg_t S1;
- int i;
- if ((S1 = alloc_float_var()) == NULL)
- if (current_reg_mes[RM_COUNT] > worst_flt_pri) {
- for (i = 0; i < nr_flt_vars; i++)
- if (flt_dat[i].pri <= worst_flt_pri &&
- flt_dat[i].size == EM_WSIZE) {
- *loc = i;
- S1 = flt_dat[i].reg;
- break;
- }
- worst_flt_pri = (unsigned)-1/2;
- for (i = 0; i < nr_flt_vars; i++)
- if (flt_dat[i].pri <= worst_flt_pri)
- worst_flt_pri = flt_dat[i].pri;
- } else
- return NULL; /* SORRY, FULL HOUSE! */
- else
- *loc = nr_flt_vars++;
- return S1;
- }
- free_all_reg_vars()
- {
- int i;
- for (i = 0; i < nr_reg_vars; i++)
- free_reg(reg_dat[i].reg);
- for (i = 0; i < nr_flt_vars; i++)
- switch (flt_dat[i].size) {
- case EM_WSIZE: free_reg(flt_dat[i].reg); break;
- case EM_DSIZE: free_double_reg(flt_dat[i].reg); break;
- }
- check_cache();
- }
- alloc_all_reg_vars()
- {
- int i;
- for (i = 0; i < nr_reg_vars; i++)
- forced_alloc_reg(reg_dat[i].reg);
- for (i = 0; i < nr_flt_vars; i++)
- switch (flt_dat[i].size) {
- case EM_WSIZE: forced_alloc_reg(flt_dat[i].reg); break;
- case EM_DSIZE:
- forced_alloc_reg(flt_dat[i].reg);
- forced_alloc_reg(flt_dat[i].reg2);
- break;
- }
- check_cache();
- }
- static params_to_regs() /* copy required parameters to registers */
- {
- int i, j;
- for (i = 0; i < nr_flt_vars; i++)
- if (flt_dat[i].offset >= 4092) {
- fprint(codefile, "set %d, %%l2\n",
- flt_dat[i].offset);
- fprint(codefile, "ld [%%l1+%%l2], %s\n",
- flt_dat[i].reg);
- if (flt_dat[i].size == EM_DSIZE) {
- fprint(codefile, "set %d, %%l2\n",
- flt_dat[i].offset+4);
- fprint(codefile, "ld [%%l1+%%l2], %s\n",
- flt_dat[i].reg2);
- }
- }
- else if (flt_dat[i].offset > 0)
- {
- fprint(codefile, "ld [%%l1+%d], %s\n",
- flt_dat[i].offset, flt_dat[i].reg);
- if (flt_dat[i].size == EM_DSIZE)
- fprint(codefile, "ld [%%l1+%d], %s\n",
- flt_dat[i].offset + 4, flt_dat[i].reg2);
- }
- for (i = 0; i < nr_reg_vars; i++)
- if (reg_dat[i].offset >= 4096) {
- fprint(codefile, "set %d, %s\n",
- reg_dat[i].offset, reg_dat[i].reg);
- fprint(codefile, "ld [%%l1+%s], %s\n",
- reg_dat[i].reg, reg_dat[i].reg);
- }
- else if (reg_dat[i].offset > 0)
- fprint(codefile, "ld [%%l1+%d], %s\n",
- reg_dat[i].offset, reg_dat[i].reg);
- }
- static cmp_flt_dat(e1, e2)
- reg_info *e1, *e2;
- {
- return (e1->offset - e2->offset);
- }
- static int even(s)
- char *s;
- {
- int l = strlen(s);
- /* Assume ASCII, where even-numbered characters (0,2,4,6,8) are even. */
- return ! (s[l-1] & 1);
- }
- static save_float_regs()
- {
- int i;
- int offset;
- qsort(flt_dat, nr_flt_vars, sizeof(flt_dat[0]), cmp_flt_dat);
- for (i = 0, offset= 0; i < nr_flt_vars; i++, offset += 8)
- if ((i+1 < nr_flt_vars &&
- flt_dat[i].offset == flt_dat[i+1].offset-4 &&
- even(flt_dat[i].reg) &&
- flt_dat[i].size == EM_FSIZE &&
- flt_dat[i+1].size == EM_FSIZE)
- || (flt_dat[i].size == EM_DSIZE)) {
- fprint(codefile, "std %s, [%%fp + %d]\n",
- flt_dat[i].reg, FLTSAV_OFFSET + offset);
- if (flt_dat[i].size != EM_DSIZE)
- ++i;
- } else
- fprint(codefile, "st %s, [%%fp + %d]\n",
- flt_dat[i].reg, FLTSAV_OFFSET + offset);
- }
- load_float_regs()
- {
- int i;
- int offset;
- for (i = 0, offset= 0; i < nr_flt_vars; i++, offset += 8)
- if ((i+1 < nr_flt_vars &&
- flt_dat[i].offset == flt_dat[i+1].offset-4 &&
- even(flt_dat[i].reg) &&
- flt_dat[i].size == EM_FSIZE &&
- flt_dat[i+1].size == EM_FSIZE)
- || (flt_dat[i].size == EM_DSIZE)) {
- fprint(codefile, "ldd [%%fp + %d], %s\n",
- FLTSAV_OFFSET + offset, flt_dat[i].reg);
- if (flt_dat[i].size != EM_DSIZE)
- ++i;
- } else
- fprint(codefile, "ld [%%fp + %d], %s\n",
- FLTSAV_OFFSET + offset, flt_dat[i].reg);
- }
- void
- C_mes_begin( ms)
- int ms;
- {
- #ifdef __solaris__
- static int inits;
- #endif
- reg_mes_nr = 0;
- in_reg_mes = (ms == ms_reg);
- if (ms == ms_gto) {
- free_all_reg_vars();
- nr_reg_vars = 0; nr_flt_vars = 0;
- fprint(codefile, "ta 3\n");
- }
- db_mes = (ms == ms_stb || ms == ms_std) ? ms : 0;
- #ifdef __solaris__
- if (db_mes && ! inits) {
- fprint(codefile, ".pushsection \".text\"\nBtext.text:\n.popsection\n");
- fprint(codefile, ".pushsection \".data\"\nBdata.data:\n.popsection\n");
- fprint(codefile, ".pushsection \".bss\"\nBbss.bss:\n.popsection\n");
- inits = 1;
- }
- #endif
- }
- static dump_reg_tabs();
- #ifdef __solaris__
- extern char *B_procnam;
- #endif
- void
- C_mes_end()
- {
- int pos;
- reg_t S1, S2;
- if (db_mes) {
- db_nul = 0;
- #ifdef __solaris__
- if (db_mes == ms_std) {
- if (db_str == 2) {
- fprint(codefile, ",1f\n1:\n");
- }
- else {
- fprint(codefile, ",1f-%s\n1:\n", B_procnam);
- }
- }
- #else
- if (db_mes == ms_std && db_str == 2) fprint(codefile,",1f\n1:\n");
- #endif
- else fprint(codefile, "\n");
- db_str = 0;
- db_mes = 0;
- db_kind = 0;
- }
- if (!in_reg_mes) /* end of some other mes */
- return;
- if (reg_mes_nr == 0) { /* end of reg_mes's */
- save_float_regs();
- params_to_regs();
- if (debug)
- dump_reg_tabs(codefile);
- return;
- }
- if (current_reg_mes[RM_COUNT] == 0) /* never used, so ignore */
- return;
- if (current_reg_mes[RM_OFFSET] >= 0)
- current_reg_mes[RM_OFFSET] += EM_BSIZE;
- if (debug)
- fprint(codefile, "\t\t! Got reg_mes: %d %d %d %d\n",
- current_reg_mes[0], current_reg_mes[1],
- current_reg_mes[2], current_reg_mes[3]);
- if (current_reg_mes[RM_TYPE] == reg_float) {
- switch(current_reg_mes[RM_SIZE]) {
- case EM_WSIZE :
- if ((S1 = my_alloc_float(current_reg_mes[RM_COUNT], &pos))
- == NULL)
- return;
- break;
- case EM_DSIZE:
- if ((S1 = my_alloc_double(current_reg_mes[RM_COUNT], &pos, &S2))
- == NULL)
- return;
- flt_dat[pos].reg2 = S2;
- default: break;
- }
- flt_dat[pos].offset = current_reg_mes[RM_OFFSET];
- flt_dat[pos].size = current_reg_mes[RM_SIZE];
- flt_dat[pos].pri = current_reg_mes[RM_COUNT];
- flt_dat[pos].reg = S1;
- } else {
- if (current_reg_mes[RM_SIZE] != EM_WSIZE)
- return; /* IGNORE THESE */
- if ((S1 = my_alloc_reg(current_reg_mes[RM_COUNT], &pos)) == NULL)
- return; /* SORRY, FULL HOUSE! */
- reg_dat[pos].offset = current_reg_mes[RM_OFFSET];
- reg_dat[pos].size = current_reg_mes[RM_SIZE];
- reg_dat[pos].pri = current_reg_mes[RM_COUNT];
- reg_dat[pos].reg = S1;
- }
- }
- extern int __gdb_flag;
- void
- C_cst( l)
- arith l;
- {
- static int correct_offset;
- if (db_mes) {
- if (! db_kind) db_kind = l;
- if (! db_str) {
- switchseg( SEGTXT);
- if (l == N_SLINE && ! __gdb_flag) {
- flush_cache();
- #ifdef __solaris__
- fprint(codefile, "call $__uX_LiB\nnop\n");
- #else
- fprint(codefile, "call ___uX_LiB\nnop\n");
- #endif
- }
- #ifdef __solaris__
- fprint(codefile, ".stabn 0x%lx,0", (long) l);
- #else
- if (db_mes == ms_std) {
- fprint(codefile, ".stabd 0x%lx,0", (long) l);
- }
- else fprint(codefile, ".stabn 0x%lx,0", (long) l);
- #endif
- db_str = 1;
- db_nul = 1;
- }
- else {
- if (correct_offset++ == -1) {
- l += EM_BSIZE;
- }
- fprint(codefile, ",0x%lx", (long) l);
- }
- if (! db_nul) {
- correct_offset = 0;
- if (l == N_PSYM && __gdb_flag) {
- correct_offset = -2;
- }
- fprint(codefile, ",0");
- db_nul = 1;
- }
- }
- if (in_reg_mes)
- current_reg_mes[reg_mes_nr++] = l;
- }
- void
- C_scon(s, l)
- register char *s;
- register arith l;
- {
- if (db_mes) {
- fprint(codefile, ".stabs \"");
- while (--l) {
- register int c = *s++;
- if (isprint(c) && c != '"' && c != '\\')
- fprint(codefile, "%c", c);
- else
- fprint(codefile, "\\%03o", c);
- }
- fprint(codefile, "\"");
- db_str = 2;
- }
- }
- void
- C_dlb(l, off)
- label l;
- arith off;
- {
- if (db_mes) {
- fprint(codefile,",");
- fprint(codefile, DLB_FMT, (long) l);
- if (off) fprint(codefile,"+%ld", (long) off);
- #ifdef __solaris__
- switch(db_kind) {
- case N_LCSYM:
- fprint(codefile, "-Bbss.bss");
- break;
- case N_STSYM:
- fprint(codefile, "-Bdata.data");
- break;
- }
- #endif
- }
- }
- void
- C_dnam(l, off)
- char *l;
- arith off;
- {
- if (db_mes) {
- fprint(codefile,",");
- fprint(codefile, DNAM_FMT, l);
- if (off) fprint(codefile,"+%ld", (long) off);
- #ifdef __solaris__
- switch(db_kind) {
- case N_LCSYM:
- fprint(codefile, "-Bbss.bss");
- break;
- case N_STSYM:
- fprint(codefile, "-Bdata.data");
- break;
- }
- #endif
- }
- }
- extern int B_procno;
- void
- C_ilb(l)
- label l;
- {
- if (db_mes) {
- fprint(codefile,",");
- fprint(codefile, ILB_FMT, B_procno, (long)l);
- #ifdef __solaris__
- fprint(codefile, "-Btext.text");
- #endif
- }
- }
- void
- C_pnam(s)
- char *s;
- {
- if (db_mes) {
- fprint(codefile,",");
- fprint(codefile, NAME_FMT, s);
- #ifdef __solaris__
- fprint(codefile, "-Btext.text");
- #endif
- }
- }
- static
- dump_reg_tabs(stream)
- FILE *stream;
- {
- int i;
- fprint(stream, "!offset\tsize\tname (%d regvars)\n", nr_reg_vars);
- for (i = 0; i < nr_reg_vars; i++)
- fprint(stream, "! %d\t%d\t%s\n", reg_dat[i].offset, reg_dat[i].size,
- reg_dat[i].reg);
- fprint(stream, "!offset\tsize\tname (%d fltvars)\n", nr_flt_vars);
- for (i = 0; i < nr_flt_vars; i++)
- fprint(stream, "! %d\t%d\t%s\n", flt_dat[i].offset, flt_dat[i].size,
- flt_dat[i].reg);
- }
- reg_t find_local(offset, reg2) /* WARNING: no size checking here! */
- int offset;
- reg_t *reg2;
- {
- int i;
- if (reg2)
- *reg2 = NULL;
- for (i = 0; i < nr_reg_vars; i++)
- if (reg_dat[i].offset == offset)
- return reg_dat[i].reg;
- for (i = 0; i < nr_flt_vars; i++)
- if (flt_dat[i].offset == offset) {
- if (flt_dat[i].size == EM_DSIZE)
- if (reg2)
- *reg2 = flt_dat[i].reg2;
- return flt_dat[i].reg;
- }
- return NULL;
- }
|