1054 lines
21 KiB
C
1054 lines
21 KiB
C
/*
|
|
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
|
*/
|
|
/* #define CODEDEBUG *//* print readable code */
|
|
#ifdef CODEDEBUG
|
|
int code_in_c=0; /* put readable code in "code" */
|
|
int tabledebug=1; /* generate code for table debugging */
|
|
#else
|
|
int code_in_c = 1; /* put code in "tables.c" */
|
|
int tabledebug = 0; /* do not generate code for table debugging */
|
|
#endif
|
|
int verbose = 0; /* print all statistics */
|
|
int use_tes; /* use top element size information */
|
|
char *c_file = "tables.c";
|
|
char *h_file = "tables.H";
|
|
char *cd_file = "code";
|
|
|
|
#ifndef NORCSID
|
|
static char rcsid[] = "$Id$";
|
|
#endif
|
|
|
|
#include <assert.h>
|
|
#include <stdio.h>
|
|
#include <ctype.h>
|
|
#include "varinfo.h"
|
|
#include "param.h"
|
|
#include "reg.h"
|
|
#include "property.h"
|
|
#include "token.h"
|
|
#include "set.h"
|
|
#include "subr.h"
|
|
#include "instruct.h"
|
|
#include "lookup.h"
|
|
#include <cgg_cg.h>
|
|
#include "pseudo.h"
|
|
#include "regvar.h"
|
|
#include "extern.h"
|
|
|
|
#define BMASK 0xFF
|
|
#define BSHIFT 8
|
|
|
|
FILE *ctable, *htable;
|
|
FILE *code;
|
|
short *lineset;
|
|
int maxline;
|
|
|
|
extern int nstrings;
|
|
extern char *l_strings[];
|
|
|
|
extern int ninstances;
|
|
extern inst_t l_instances[];
|
|
|
|
extern int nmoves;
|
|
extern move_t l_moves[];
|
|
extern int ntests;
|
|
extern test_t l_tests[];
|
|
extern int nstacks;
|
|
extern c1_t l_stacks[];
|
|
extern int ncoercs;
|
|
extern c3_t l_coercs[];
|
|
extern int nsplit, maxsplit;
|
|
extern c2_t l_split[];
|
|
extern set_t l_sets[];
|
|
|
|
int maxallreg = 0;
|
|
int maxregvars = 0;
|
|
int setsize;
|
|
|
|
int prevind = 0;
|
|
int npatbytes = -1;
|
|
char pattern[MAXPATBYTES];
|
|
int pathash[256];
|
|
|
|
extern int npatterns;
|
|
extern int patindex[];
|
|
extern int empatlen;
|
|
extern int emmnem[];
|
|
extern int empatexpr;
|
|
|
|
extern node_t nodes[];
|
|
extern int nnodes;
|
|
|
|
extern char * filename;
|
|
|
|
/* Forward declarations */
|
|
static void patbyte(int);
|
|
static void patshort(int);
|
|
static void pat(int);
|
|
|
|
void opnfile(FILE **f, char *s)
|
|
{
|
|
|
|
if ((*f = fopen(s, "w")) == NULL)
|
|
fatal("Can't create %s", s);
|
|
}
|
|
|
|
void unlfile(FILE *f, char *s)
|
|
{
|
|
if (f)
|
|
fclose(f);
|
|
if (remove(s) < 0)
|
|
error("%s incorrect, must be removed!!", s);
|
|
}
|
|
|
|
void initio(void)
|
|
{
|
|
|
|
opnfile(&ctable, c_file);
|
|
opnfile(&htable, h_file);
|
|
if (code_in_c)
|
|
fprintf(ctable, "char coderules[] = {");
|
|
else
|
|
opnfile(&code, cd_file);
|
|
patbyte(0);
|
|
if (tabledebug)
|
|
lineset = (short *) myalloc(SZOFSET(MAXSOURCELINES) * sizeof(short));
|
|
}
|
|
|
|
void finishcode(void)
|
|
{
|
|
|
|
if (code_in_c)
|
|
fprintf(ctable, "\n};\n\n");
|
|
fprintf(ctable, "int allsetno = %d;\n", allsetno);
|
|
if (tabledebug)
|
|
{
|
|
FILE *fd;
|
|
int sz;
|
|
|
|
fd = fopen("lineset","wb");
|
|
if (fd != NULL)
|
|
{
|
|
sz = SZOFSET(maxline) * 2;
|
|
fwrite(&sz,1,sizeof(int),fd);
|
|
fwrite(lineset,1,sz,fd);
|
|
fclose(fd);
|
|
}
|
|
else
|
|
error("Can't create lineset");
|
|
}
|
|
}
|
|
|
|
void errorexit(void)
|
|
{
|
|
unlfile(ctable, c_file);
|
|
unlfile(htable, h_file);
|
|
if (!code_in_c)
|
|
unlfile(code, cd_file);
|
|
}
|
|
|
|
#ifdef CODEDEBUG
|
|
#define code8(x) fprintf(code,"%s","x")
|
|
#define code8nl(x) fprintf(code,"%s\n","x")
|
|
#define code53(x,y) fprintf(code,"%s-%d","x",y)
|
|
#define codeint(x) fprintf(code," %d",x)
|
|
#define codenl() fprintf(code,"\n")
|
|
#else
|
|
#define codenl()
|
|
#define code8nl(x) code8(x)
|
|
|
|
void code8(int x)
|
|
{
|
|
|
|
codeindex++;
|
|
if (code_in_c)
|
|
fprintf(ctable, "%d,", x & 0377);
|
|
else
|
|
putc(x, code);
|
|
}
|
|
|
|
void code53(int x, int y)
|
|
{
|
|
code8(x + (y << 5));
|
|
}
|
|
|
|
void codeint(int x)
|
|
{
|
|
assert(x >= 0 && x <= 32767);
|
|
if (x < 128)
|
|
{
|
|
code8(x);
|
|
}
|
|
else
|
|
{
|
|
code8(x / 256 + 128);
|
|
code8(x % 256);
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
void outpatterns(void)
|
|
{
|
|
register int i;
|
|
|
|
if (!inproc)
|
|
{
|
|
patbyte(0);
|
|
patshort(prevind);
|
|
prevind = npatbytes - 2;
|
|
patbyte(empatlen);
|
|
for (i = 0; i < empatlen; i++)
|
|
patbyte(emmnem[i]);
|
|
pat(empatexpr);
|
|
}
|
|
if (callproc == 0)
|
|
{
|
|
patbyte(npatterns);
|
|
for (i = 0; i < npatterns; i++)
|
|
pat(patindex[i]);
|
|
}
|
|
else
|
|
{
|
|
patbyte(0);
|
|
pat(callproc);
|
|
pat(nprocargs);
|
|
for (i = 0; i < nprocargs; i++)
|
|
pat(procarg[i]);
|
|
}
|
|
}
|
|
|
|
static void pat(int n)
|
|
{
|
|
|
|
assert(n >= 0);
|
|
if (n < 128)
|
|
patbyte(n);
|
|
else
|
|
{
|
|
patbyte(n / 256 + 128);
|
|
patbyte(n % 256);
|
|
}
|
|
}
|
|
|
|
static void patshort(int n)
|
|
{
|
|
|
|
patbyte(n % 256);
|
|
patbyte(n / 256);
|
|
}
|
|
|
|
static void patbyte(int n)
|
|
{
|
|
|
|
NEXT(npatbytes, MAXPATBYTES, "Pattern bytes");
|
|
pattern[npatbytes] = n;
|
|
}
|
|
|
|
void hashpatterns(void)
|
|
{
|
|
short index;
|
|
register char *bp, *tp;
|
|
register short i;
|
|
unsigned short hashvalue;
|
|
int patlen;
|
|
|
|
index = prevind;
|
|
while (index != 0)
|
|
{
|
|
bp = &pattern[index];
|
|
tp = &bp[PO_MATCH];
|
|
i = *tp++ & BMASK;
|
|
if (i == BMASK)
|
|
{
|
|
i = *tp++ & BMASK;
|
|
i |= (*tp++ & BMASK) << BSHIFT;
|
|
}
|
|
patlen = i;
|
|
hashvalue = 0;
|
|
switch (patlen)
|
|
{
|
|
default: /* 3 or more */
|
|
hashvalue = (hashvalue << 4) ^ (*tp++ & BMASK);
|
|
case 2:
|
|
hashvalue = (hashvalue << 4) ^ (*tp++ & BMASK);
|
|
case 1:
|
|
hashvalue = (hashvalue << 4) ^ (*tp++ & BMASK);
|
|
}
|
|
assert(hashvalue!= ILLHASH);
|
|
i = index;
|
|
index = (bp[PO_NEXT] & BMASK) | (bp[PO_NEXT + 1] << BSHIFT);
|
|
bp[PO_HASH] = hashvalue >> BSHIFT;
|
|
hashvalue &= BMASK;
|
|
bp[PO_NEXT] = pathash[hashvalue] & BMASK;
|
|
bp[PO_NEXT + 1] = pathash[hashvalue] >> BSHIFT;
|
|
pathash[hashvalue] = i;
|
|
}
|
|
}
|
|
|
|
void outincludes(void)
|
|
{
|
|
|
|
fprintf(ctable, "#include \"param.h\"\n");
|
|
fprintf(ctable, "#include \"tables.h\"\n");
|
|
fprintf(ctable, "#include \"types.h\"\n");
|
|
fprintf(ctable, "#include <cgg_cg.h>\n");
|
|
fprintf(ctable, "#include \"data.h\"\n");
|
|
}
|
|
|
|
void outregs(void)
|
|
{
|
|
register int i, j, k;
|
|
short rset[SZOFSET(MAXREGS)];
|
|
short clashlist[MAXREGS * MAXREGS];
|
|
int iclashlist = 0;
|
|
int t, ready;
|
|
|
|
fprintf(ctable, "char stregclass[] = {\n");
|
|
for (i = 0; i < nregs; i++)
|
|
fprintf(ctable, "\t%d,\n", l_regs[i].ri_class);
|
|
fprintf(ctable, "};\n\nstruct reginfo machregs[] = {\n{0},\n");
|
|
for (i = 1; i < nregs; i++)
|
|
{
|
|
fprintf(ctable, "{%d,%d", strlookup(l_regs[i].ri_repr),
|
|
l_regs[i].ri_size);
|
|
if (maxmembers != 0)
|
|
{
|
|
fprintf(ctable, ",{");
|
|
for (j = 0; j < maxmembers; j++)
|
|
fprintf(ctable, "%d,", l_regs[i].ri_memb[j]);
|
|
/* now compute and print set of registers
|
|
* that clashes with this register.
|
|
* A register clashes with al its children (and theirs)
|
|
* and with all their parents.
|
|
*/
|
|
for (j = 0; j < SZOFSET(MAXREGS); j++)
|
|
rset[j] = 0;
|
|
BIS(rset, i);
|
|
do
|
|
{
|
|
ready = 1;
|
|
for (j = 1; j < nregs; j++)
|
|
if (BIT(rset, j))
|
|
for (k = 0; k < 2; k++)
|
|
if ((t = l_regs[j].ri_memb[k]) != 0)
|
|
{
|
|
if (BIT(rset,t) == 0)
|
|
ready = 0;
|
|
BIS(rset, t);
|
|
}
|
|
} while (!ready);
|
|
do
|
|
{
|
|
ready = 1;
|
|
for (j = 1; j < nregs; j++)
|
|
for (k = 0; k < 2; k++)
|
|
if ((t = l_regs[j].ri_memb[k]) != 0)
|
|
if (BIT(rset, t))
|
|
{
|
|
if (BIT(rset,j) == 0)
|
|
ready = 0;
|
|
BIS(rset, j);
|
|
}
|
|
} while (!ready);
|
|
fprintf(ctable, "},{");
|
|
for (j = 0; j < SZOFSET(nregs); j++)
|
|
fprintf(ctable, "0%o,", rset[j] & 0xFFFF);
|
|
fprintf(ctable, "}, %d", iclashlist);
|
|
for (j = 1; j < nregs; j++)
|
|
{
|
|
if (BIT(rset, j))
|
|
clashlist[iclashlist++] = j;
|
|
}
|
|
clashlist[iclashlist++] = 0;
|
|
}
|
|
/*
|
|
* Write .r_refcount = 1 for register variables or 0
|
|
* for other registers.
|
|
*
|
|
* reglap: Write .r_refcount = 0 if the register
|
|
* variable has a subregister.
|
|
*/
|
|
fprintf(ctable, ",%d",
|
|
l_regs[i].ri_rregvar >= 0 && l_regs[i].ri_memb[0] == 0);
|
|
fprintf(ctable, "},\n");
|
|
}
|
|
fprintf(ctable, "};\n\n short clashlist[] = {\n\t");
|
|
for (i = 0; i < iclashlist; i++)
|
|
{
|
|
fprintf(ctable, "%d, ", clashlist[i]);
|
|
if (clashlist[i] == 0)
|
|
fprintf(ctable, "\n\t");
|
|
}
|
|
fprintf(ctable, "0};\n\n");
|
|
}
|
|
|
|
void outregvars(void)
|
|
{
|
|
register int i, j;
|
|
|
|
fprintf(htable, "#define REGVARS\n");
|
|
if (reglap != 0)
|
|
fprintf(htable, "#define REGLAP\n");
|
|
fprintf(ctable, "#include \"regvar.h\"\n");
|
|
fprintf(ctable, "int nregvar[4] = { ");
|
|
for (i = 0; i < 4; i++)
|
|
{
|
|
fprintf(ctable, "%d, ", nregvar[i]);
|
|
if (nregvar[i] > maxregvars)
|
|
maxregvars = nregvar[i];
|
|
}
|
|
fprintf(ctable, "};\n");
|
|
for (i = 0; i < 4; i++)
|
|
if (nregvar[i] > 0)
|
|
fprintf(ctable, "struct regassigned ratar%d[%d];\n", i, nregvar[i]);
|
|
for (i = 0; i < 4; i++)
|
|
if (nregvar[i] > 0)
|
|
{
|
|
fprintf(ctable, "int rvtar%d[] = {", i);
|
|
for (j = 0; j < nregvar[i]; j++)
|
|
fprintf(ctable, "%d,", rvnumbers[i][j]);
|
|
fprintf(ctable, "};\n");
|
|
}
|
|
fprintf(ctable, "\nint *rvnumbers[] = {\n");
|
|
for (i = 0; i < 4; i++)
|
|
if (nregvar[i] > 0)
|
|
fprintf(ctable, "\trvtar%d,\n", i);
|
|
else
|
|
fprintf(ctable, "\t0,\n");
|
|
fprintf(ctable, "};\n\nstruct regassigned *regassigned[] = {\n");
|
|
for (i = 0; i < 4; i++)
|
|
if (nregvar[i] > 0)
|
|
fprintf(ctable, "\tratar%d,\n", i);
|
|
else
|
|
fprintf(ctable, "\t0,\n");
|
|
fprintf(ctable, "};\n");
|
|
}
|
|
|
|
int typeconv(int n)
|
|
{
|
|
|
|
if (n >= 0)
|
|
return (2);
|
|
if (n == -1)
|
|
return (1);
|
|
if (n == -2)
|
|
return (3);
|
|
assert(n == -3);
|
|
return (0);
|
|
}
|
|
|
|
static int is_ascii(int c)
|
|
{
|
|
if ((c >= 0) && (c <= 127))
|
|
return 1;
|
|
return 0;
|
|
}
|
|
|
|
void outfmt(register char *p)
|
|
{
|
|
register int c;
|
|
fprintf(ctable, "\"");
|
|
while ((c = (*p++ & 0377)) != 0)
|
|
{
|
|
if (!is_ascii(c) || iscntrl(c))
|
|
{
|
|
fprintf(ctable, "\\%c%c%c", ((c & ~0300) >> 6) + '0',
|
|
((c & 070) >> 3) + '0', (c & 07) + '0');
|
|
}
|
|
else
|
|
fprintf(ctable, "%c", c);
|
|
}
|
|
fprintf(ctable, "\"");
|
|
}
|
|
|
|
void outtokens(void)
|
|
{
|
|
register int tokno, i;
|
|
register token_p tp;
|
|
|
|
fprintf(ctable, "tkdef_t tokens[] = {{0},\n");
|
|
for (tokno = 1; tokno < ntokens; tokno++)
|
|
{
|
|
tp = l_tokens[tokno];
|
|
fprintf(ctable, "/* %3d */{%d,{%d,%d},{", tokno, tp->tk_size,
|
|
tp->tk_cost.ct_space, tp->tk_cost.ct_time);
|
|
for (i = 0; i < maxtokensize; i++)
|
|
fprintf(ctable, "%d,", typeconv(tp->tk_att[i].ta_type));
|
|
fprintf(ctable, "},%d},\t/* ", tp->tk_format);
|
|
if (tp->tk_format >= 0)
|
|
outfmt(l_strings[tp->tk_format]);
|
|
else
|
|
fprintf(ctable, "(no format)");
|
|
fprintf(ctable, " */\n");
|
|
}
|
|
fprintf(ctable, "{0}};\n\n");
|
|
}
|
|
|
|
void outenodes(void)
|
|
{
|
|
register node_p np;
|
|
|
|
fprintf(ctable, "node_t enodes[] = {\n");
|
|
for (np = nodes; np < &nodes[nnodes]; np++)
|
|
fprintf(ctable, "{%d,%d,%d},\n", np->ex_operator, np->ex_lnode,
|
|
np->ex_rnode);
|
|
fprintf(ctable, "};\n\n");
|
|
}
|
|
|
|
void outstrings(void)
|
|
{
|
|
register int i;
|
|
#if 0
|
|
register char *p;
|
|
register int c;
|
|
#endif
|
|
|
|
if (tabledebug)
|
|
fprintf(ctable, "char *tablename = \"%s\";\n", filename);
|
|
fprintf(ctable, "string codestrings[] = {\n");
|
|
for (i = 0; i < nstrings; i++)
|
|
{
|
|
fprintf(ctable, "\t");
|
|
outfmt(l_strings[i]);
|
|
#if 0
|
|
while ((c= (*p++&0377))!=0)
|
|
{
|
|
if (! isascii(c) || iscntrl(c))
|
|
{
|
|
fprintf(ctable,"\\%c%c%c",
|
|
((c&~0300)>>6) + '0', ((c&070)>>3)+'0',
|
|
(c&07)+'0');
|
|
}
|
|
else fprintf(ctable, "%c",c);
|
|
}
|
|
fprintf(ctable,"\",\n");
|
|
#endif
|
|
fprintf(ctable, ",\n");
|
|
}
|
|
fprintf(ctable, "};\n\n");
|
|
}
|
|
|
|
extern set_t unstackset;
|
|
|
|
void outsets(void)
|
|
{
|
|
register int i;
|
|
register set_p sp;
|
|
|
|
fprintf(ctable, "set_t machsets[] = {\n");
|
|
for (sp = l_sets; sp < &l_sets[nsets]; sp++)
|
|
{
|
|
fprintf(ctable, "/* %3ld */ {%3d,{", (long) (sp - l_sets),
|
|
sp->set_size);
|
|
for (i = 0; i < setsize; i++)
|
|
fprintf(ctable, "0x%x,", sp->set_val[i] & 0xFFFF);
|
|
fprintf(ctable, "}},\n");
|
|
}
|
|
fprintf(ctable, "};\n\n");
|
|
|
|
fprintf(ctable, "set_t unstackset = { %3d,{\n", unstackset.set_size);
|
|
for (i = 0; i < setsize; i++)
|
|
fprintf(ctable, "0x%x,", unstackset.set_val[i] & 0xFFFF);
|
|
fprintf(ctable, "}};\n\n");
|
|
}
|
|
|
|
void outinstances(void)
|
|
{
|
|
register inst_p ip;
|
|
register int i;
|
|
|
|
fprintf(ctable, "inst_t tokeninstances[] = {\n");
|
|
for (ip = l_instances; ip < &l_instances[ninstances]; ip++)
|
|
{
|
|
fprintf(ctable, "{ %d, {", ip->in_which);
|
|
for (i = 0; i <= maxtokensize; i++)
|
|
fprintf(ctable, "%d,", ip->in_info[i]);
|
|
fprintf(ctable, "}},\n");
|
|
}
|
|
fprintf(ctable, "};\n\n");
|
|
}
|
|
|
|
void outmoves(void)
|
|
{
|
|
register move_p mp;
|
|
|
|
fprintf(ctable, "move_t moves[] = {\n");
|
|
for (mp = l_moves; mp < &l_moves[nmoves]; mp++)
|
|
fprintf(ctable, "{%d,%d,%d,%d,%d},\n", mp->m_set1, mp->m_expr1,
|
|
mp->m_set2, mp->m_expr2, mp->m_cindex);
|
|
fprintf(ctable, "{-1}\n};\n\n");
|
|
}
|
|
|
|
void outtests(void)
|
|
{
|
|
register test_p tp;
|
|
|
|
fprintf(ctable, "test_t tests[] = {\n");
|
|
for (tp = l_tests; tp < &l_tests[ntests]; tp++)
|
|
fprintf(ctable, "{%d,%d,%d},\n", tp->t_set, tp->t_expr, tp->t_cindex);
|
|
fprintf(ctable, "{-1}\n};\n\n");
|
|
}
|
|
|
|
void outstacks(void)
|
|
{
|
|
register c1_p cp;
|
|
|
|
fprintf(ctable, "c1_t c1coercs[] = {\n");
|
|
for (cp = l_stacks; cp < &l_stacks[nstacks]; cp++)
|
|
fprintf(ctable, "{%d,%d,%d,%d},\n", cp->c1_texpno, cp->c1_expr,
|
|
cp->c1_prop, cp->c1_codep);
|
|
fprintf(ctable, "{-1}\n};\n\n");
|
|
}
|
|
|
|
void outsplits(void)
|
|
{
|
|
register c2_p cp;
|
|
register int i;
|
|
|
|
fprintf(ctable, "c2_t c2coercs[] = {\n");
|
|
for (cp = l_split; cp < &l_split[nsplit]; cp++)
|
|
{
|
|
fprintf(ctable, "{%d,%d,%d,{", cp->c2_texpno, cp->c2_expr,
|
|
cp->c2_nsplit);
|
|
for (i = 0; i < maxsplit; i++)
|
|
fprintf(ctable, "%d,", cp->c2_repl[i]);
|
|
fprintf(ctable, "},%d},\n", cp->c2_codep);
|
|
}
|
|
fprintf(ctable, "{-1}\n};\n\n");
|
|
}
|
|
|
|
void outcoercs(void)
|
|
{
|
|
register c3_p cp;
|
|
|
|
fprintf(ctable, "c3_t c3coercs[] = {\n");
|
|
for (cp = l_coercs; cp < &l_coercs[ncoercs]; cp++)
|
|
fprintf(ctable, "{%d,%d,%d,%d,%d},\n", cp->c3_texpno, cp->c3_expr,
|
|
cp->c3_prop, cp->c3_repl, cp->c3_codep);
|
|
fprintf(ctable, "{-1}\n};\n\n");
|
|
}
|
|
|
|
void outproplists(void)
|
|
{
|
|
register int propno;
|
|
register int regno;
|
|
|
|
for (propno = 0; propno < nprops; propno++)
|
|
{
|
|
fprintf(ctable, "struct reginfo *rlist%d[] = {\n", propno);
|
|
for (regno = 1; regno < nregs; regno++)
|
|
if (BIT(l_props[propno].pr_regset, regno))
|
|
fprintf(ctable, "&machregs[%d],\n", regno);
|
|
fprintf(ctable, "0\n};\n");
|
|
}
|
|
fprintf(ctable, "struct reginfo **reglist[] = {\n");
|
|
for (propno = 0; propno < nprops; propno++)
|
|
fprintf(ctable, "rlist%d,\n", propno);
|
|
fprintf(ctable, "};\n\n");
|
|
}
|
|
|
|
void outconsts(void)
|
|
{
|
|
|
|
fprintf(ctable, "unsigned cc1 = %u;\n", fc1);
|
|
fprintf(ctable, "unsigned cc2 = %u;\n", fc2);
|
|
fprintf(ctable, "unsigned cc3 = %u;\n", fc3);
|
|
fprintf(ctable, "unsigned cc4 = %u;\n", fc4);
|
|
}
|
|
|
|
void cdef(char *s, int n)
|
|
{
|
|
|
|
fprintf(htable, "#define %s %d\n", s, n);
|
|
}
|
|
|
|
void passon(char *s)
|
|
{
|
|
char buf[32];
|
|
|
|
sprintf(buf, "T%s", s);
|
|
cdef(buf, cmustbeset(s));
|
|
}
|
|
|
|
void outdefs(void)
|
|
{
|
|
register symbol *sy_p;
|
|
extern int maxempatlen, maxrule;
|
|
char *wrdfmt;
|
|
|
|
passon("EM_WSIZE");
|
|
passon("EM_PSIZE");
|
|
passon("EM_BSIZE");
|
|
if ((sy_p = lookup("FORMAT", symsconst, justlooking)) != 0)
|
|
{
|
|
wrdfmt = l_strings[sy_p->sy_value.syv_stringno];
|
|
fprintf(htable, "#define WRD_FMT \"%s\"\n", wrdfmt);
|
|
}
|
|
cdef("MAXALLREG", maxallreg);
|
|
cdef("SETSIZE", setsize);
|
|
cdef("NREGS", nregs);
|
|
cdef("REGSETSIZE", SZOFSET(nregs));
|
|
cdef("TOKENSIZE", maxtokensize);
|
|
cdef("MAXMEMBERS", maxmembers);
|
|
cdef("LONGESTPATTERN", maxempatlen);
|
|
cdef("MAXPATLEN", maxtokpatlen);
|
|
cdef("MAXREPLLEN", maxtokrepllen);
|
|
cdef("MAXEMREPLLEN", maxemrepllen);
|
|
cdef("MAXPROCARG", maxprocargs);
|
|
cdef("MAXRULE", maxrule < 16 ? 16 : maxrule);
|
|
if (nsplit > 0)
|
|
{
|
|
cdef("MAXSPLIT", maxsplit);
|
|
}
|
|
if (tabledebug)
|
|
cdef("TABLEDEBUG", 1);
|
|
if (use_tes)
|
|
cdef("USE_TES", 1);
|
|
}
|
|
|
|
void outars(void)
|
|
{
|
|
register int i;
|
|
|
|
if (code_in_c)
|
|
fprintf(htable, "#define CODEINC 1\n");
|
|
else
|
|
{
|
|
fprintf(ctable, "char coderules[%d];\n", codeindex);
|
|
fprintf(ctable, "int ncodebytes=%d;\n", codeindex);
|
|
}
|
|
fprintf(ctable, "char pattern[%d]={\n", npatbytes + 1);
|
|
for (i = 0; i <= npatbytes; i++)
|
|
{
|
|
fprintf(ctable, "%d,%c", pattern[i] & BMASK, i % 16 == 15 ? '\n' : ' ');
|
|
}
|
|
fprintf(ctable, "};\n\n");
|
|
fprintf(ctable, "int pathash[256]={\n");
|
|
for (i = 0; i < 256; i++)
|
|
{
|
|
fprintf(ctable, "%d,%c", pathash[i] & 0xFFFF, i % 10 == 9 ? '\n' : ' ');
|
|
}
|
|
fprintf(ctable, "};\n");
|
|
}
|
|
|
|
void finishio(void)
|
|
{
|
|
extern int nregs;
|
|
|
|
finishcode();
|
|
hashpatterns();
|
|
setsize = SZOFSET(nregs + ntokens);
|
|
outdefs();
|
|
outincludes();
|
|
outregs();
|
|
outtokens();
|
|
outenodes();
|
|
outstrings();
|
|
outsets();
|
|
outinstances();
|
|
outmoves();
|
|
outtests();
|
|
outstacks();
|
|
if (nsplit > 0)
|
|
outsplits();
|
|
outcoercs();
|
|
outproplists();
|
|
outconsts();
|
|
if (rvused)
|
|
outregvars();
|
|
outars();
|
|
}
|
|
|
|
void codecoco(int cocono)
|
|
{
|
|
|
|
if (cocono == -1)
|
|
return;
|
|
code8(DO_SETCC);
|
|
codeint(cocono);
|
|
codenl();
|
|
}
|
|
|
|
void dopattern(int stackcoerc, varinfo *kills, varinfo *allocates,
|
|
varinfo *generates, varinfo *yields, varinfo *leaving)
|
|
{
|
|
register int i;
|
|
int n, nops;
|
|
register struct varinfo *vp, *vivp;
|
|
register instr_p instp;
|
|
int al, deal;
|
|
int vil;
|
|
int cocono = -1;
|
|
cost_t totcost;
|
|
int nremoves;
|
|
int removelist[100];
|
|
static char tlab[] = "0:";
|
|
extern int optexact, optstack, startline;
|
|
extern char *filename;
|
|
extern int lineno;
|
|
|
|
#ifdef CODEDEBUG
|
|
fprintf(code,"Code(%d) at \"%s\", line %d\n",stackcoerc,filename,lineno);
|
|
#endif
|
|
if (code_in_c)
|
|
fprintf(ctable, "\n/* \"%s\", line %d */ ", filename, lineno);
|
|
if (tabledebug)
|
|
{
|
|
code8(DO_DLINE);
|
|
codeint(startline);
|
|
codenl();
|
|
if (startline < MAXSOURCELINES)
|
|
{
|
|
if (startline > maxline)
|
|
maxline = startline;
|
|
BIS(lineset, startline);
|
|
}
|
|
else
|
|
{
|
|
static int beenhere = 0;
|
|
|
|
if (!beenhere)
|
|
{
|
|
beenhere++;
|
|
error("Too many source lines for table debug");
|
|
}
|
|
}
|
|
}
|
|
/* MATCH part */
|
|
if (tokpatlen)
|
|
{
|
|
if (optexact)
|
|
if (optstack)
|
|
code53(DO_XXMATCH, tokpatlen);
|
|
else
|
|
code53(DO_XMATCH, tokpatlen);
|
|
else
|
|
code53(DO_MATCH, tokpatlen);
|
|
for (i = 0; i < tokpatlen; i++)
|
|
codeint(tokpatset[i]);
|
|
codenl();
|
|
}
|
|
else if (stackcoerc)
|
|
code8nl(DO_COERC);
|
|
if (optstack)
|
|
{
|
|
code53(DO_TOSTACK, 0);
|
|
codeint(allsetno);
|
|
codenl();
|
|
}
|
|
/* The kills */
|
|
for (vp = kills; vp != 0; vp = vp->vi_next)
|
|
{
|
|
if (vp->vi_int[1] != 0)
|
|
{
|
|
code53(DO_REMOVE, 1);
|
|
codeint(vp->vi_int[0]);
|
|
codeint(vp->vi_int[1]);
|
|
}
|
|
else if (vp->vi_int[0] >= 0)
|
|
{
|
|
code53(DO_REMOVE, 0);
|
|
codeint(vp->vi_int[0]);
|
|
}
|
|
else
|
|
{
|
|
code8(DO_KILLREG);
|
|
codeint(-vp->vi_int[0] - 1);
|
|
} codenl();
|
|
}
|
|
nremoves = 0;
|
|
for (vp = generates; vp != 0; vp = vp->vi_next)
|
|
{
|
|
if (vp->vi_int[0] != INSREMOVE)
|
|
continue;
|
|
for (i = 0; i < nremoves; i++)
|
|
if (vp->vi_int[1] == removelist[i])
|
|
break;
|
|
if (i == nremoves)
|
|
{
|
|
assert(nremoves < (sizeof(removelist) / sizeof(int)));
|
|
removelist[nremoves++] = vp->vi_int[1];
|
|
}
|
|
}
|
|
for (i = 0; i < nremoves; i++)
|
|
{
|
|
code8(DO_RREMOVE);
|
|
codeint(removelist[i]);
|
|
codenl();
|
|
}
|
|
/* allocate part */
|
|
deal = 0;
|
|
al = 0;
|
|
for (vp = allocates; vp != 0; vp = vp->vi_next)
|
|
{
|
|
if (vp->vi_int[0] == -1)
|
|
{ /* Deallocate */
|
|
deal++;
|
|
code8(DO_DEALLOCATE);
|
|
codeint(vp->vi_int[1]);
|
|
codenl();
|
|
}
|
|
else
|
|
{
|
|
if (vp->vi_int[1] == 0)
|
|
{
|
|
code53(DO_ALLOCATE, 0);
|
|
codeint(vp->vi_int[0]);
|
|
codenl();
|
|
}
|
|
else
|
|
{
|
|
code53(DO_ALLOCATE, 1);
|
|
codeint(vp->vi_int[0]);
|
|
codeint(vp->vi_int[1]);
|
|
codenl();
|
|
}
|
|
al++;
|
|
}
|
|
}
|
|
if (deal)
|
|
code8nl(DO_REALLOCATE);
|
|
if (al > maxallreg)
|
|
maxallreg = al;
|
|
totcost.ct_space = 0;
|
|
totcost.ct_time = 0;
|
|
for (vp = generates; vp != 0; vp = vp->vi_next)
|
|
{
|
|
n = vp->vi_int[0];
|
|
switch (n)
|
|
{
|
|
default:
|
|
assert(n >= 0);
|
|
instp = &l_instr[n];
|
|
nops = instp->i_nops;
|
|
code53(DO_INSTR, nops);
|
|
if (vp->vi_int[1] == 0)
|
|
{
|
|
codeint(instp->i_asname);
|
|
}
|
|
else
|
|
{
|
|
codeint(10000 + vp->vi_int[1]);
|
|
}
|
|
vivp = vp->vi_vi;
|
|
for (i = 0; i < nops; i++)
|
|
{
|
|
codeint(vivp->vi_int[0]);
|
|
vivp = vivp->vi_vi;
|
|
}
|
|
codenl();
|
|
totcost.ct_space += instp->i_cost.ct_space;
|
|
totcost.ct_time += instp->i_cost.ct_time;
|
|
break;
|
|
case INSREMOVE:
|
|
break;
|
|
case INSMOVE:
|
|
codecoco(cocono);
|
|
code8(DO_MOVE);
|
|
codeint(vp->vi_int[1]);
|
|
codeint(vp->vi_int[2]);
|
|
codenl();
|
|
break;
|
|
case INSTEST:
|
|
codecoco(cocono);
|
|
code8(DO_TEST);
|
|
codeint(vp->vi_int[1]);
|
|
codenl();
|
|
break;
|
|
case INSPRETURN:
|
|
code8(DO_PRETURN);
|
|
codenl();
|
|
break;
|
|
case INSTLAB:
|
|
cocono = 0;
|
|
tlab[0] = vp->vi_int[1] + '0';
|
|
code53(DO_INSTR, 0);
|
|
codeint(strlookup(tlab));
|
|
codenl();
|
|
break;
|
|
case INSSETCC:
|
|
cocono = vp->vi_int[1];
|
|
break;
|
|
case INSERASE:
|
|
code8(DO_ERASE);
|
|
codeint(vp->vi_int[1]);
|
|
codenl();
|
|
break;
|
|
case INSLABDEF:
|
|
cocono = 0;
|
|
code8(DO_LABDEF);
|
|
codeint(vp->vi_int[1]);
|
|
codenl();
|
|
break;
|
|
}
|
|
}
|
|
codecoco(cocono);
|
|
vil = vilength(yields);
|
|
if (vil != 0 || tokpatlen != 0 || allocates != 0)
|
|
{
|
|
code53(DO_TOKREPLACE, vilength(yields));
|
|
for (vp = yields; vp != 0; vp = vp->vi_next)
|
|
{
|
|
codeint(vp->vi_int[0]);
|
|
} codenl();
|
|
}
|
|
if (leaving != 0)
|
|
{
|
|
code53(DO_EMREPLACE, vilength(leaving));
|
|
while (leaving != 0)
|
|
{
|
|
codeint(leaving->vi_int[0]);
|
|
codeint(leaving->vi_int[1]);
|
|
leaving = leaving->vi_next;
|
|
} codenl();
|
|
}
|
|
if (totcost.ct_space != 0 || totcost.ct_time != 0)
|
|
{
|
|
code8(DO_COST);
|
|
codeint(totcost.ct_space);
|
|
codeint(totcost.ct_time);
|
|
codenl();
|
|
}
|
|
if (empatlen == 0 && !inproc)
|
|
code8nl(DO_RETURN);
|
|
else
|
|
code8nl(DO_NEXTEM);
|
|
}
|
|
|
|
void used(char *resource, int use, int max)
|
|
{
|
|
|
|
if (verbose || 4 * use > 3 * max)
|
|
fprintf(stderr, "%s %d(%d)\n", resource, use, max);
|
|
}
|
|
|
|
void statistics(void)
|
|
{
|
|
extern int nnodes, maxempatlen, maxrule;
|
|
|
|
used("Registers", nregs, MAXREGS);
|
|
used("Properties", nprops, MAXPROPS);
|
|
used("Tokens", ntokens, MAXTOKENS);
|
|
used("Tokensize", maxtokensize, MAXATT);
|
|
used("Sets", nsets, MAXSETS);
|
|
used("Instructions", ninstr, MAXINSTR);
|
|
used("Strings", nstrings, MAXSTRINGS);
|
|
used("Exp-nodes", nnodes, MAXNODES);
|
|
used("EM-pat length", maxempatlen, EMPATMAX);
|
|
used("rules/EM-pattern", maxrule, MAXPATTERNS);
|
|
used("Allocates/rule", maxallreg, MAXALLREG);
|
|
used("Instances", ninstances, MAXINSTANCES);
|
|
used("Moves", nmoves, MAXMOVES);
|
|
used("Tests", ntests, MAXTESTS);
|
|
used("Stacks", nstacks, MAXSTACKS);
|
|
used("1->1 Coercions", ncoercs, MAXCOERCS);
|
|
used("Splitting coercions", nsplit, MAXSPLCOERC);
|
|
used("Register variables", maxregvars, MAXREGVAR);
|
|
used("Pat bytes", npatbytes + 1, MAXPATBYTES);
|
|
if (tabledebug)
|
|
used("Source lines", maxline, MAXSOURCELINES);
|
|
}
|