ack/util/cgg/main.c

1162 lines
24 KiB
C
Raw Normal View History

#include <stdlib.h>
1988-07-14 09:15:21 +00:00
#include <stdio.h>
#include <assert.h>
#include <ctype.h>
#include <string.h>
2019-05-10 17:13:43 +00:00
#include "em_spec.h"
#include "em_flag.h"
#include "em_reg.h"
1988-07-14 09:15:21 +00:00
2019-05-10 17:13:43 +00:00
#define EXTERN extern
#include "booth.h"
2019-05-10 17:13:43 +00:00
#undef EXTERN
2019-05-10 17:13:43 +00:00
/* Forward local declarations. */
static void debug(void);
static void verbose(void);
static void outregvar(void);
static void finishio(void);
static void inittables(void);
static void initio(void);
static int eqregclass(int r1, int r2);
static void compueq(void);
char *myalloc(int n)
{
register char *p;
2019-05-10 17:13:43 +00:00
p = malloc((unsigned) n);
if (p == 0)
{
yyerror("Out of core");
exit(1);
}
2019-05-10 17:13:43 +00:00
return (p);
}
2019-05-10 17:13:43 +00:00
void tstint(expr_t e)
{
2019-05-10 17:13:43 +00:00
if (e.expr_typ != TYPINT)
yyerror("Must be integer expression");
}
2019-05-10 17:13:43 +00:00
void tstbool(expr_t e)
{
2019-05-10 17:13:43 +00:00
if (e.expr_typ != TYPBOOL)
yyerror("Must be boolean expression");
}
2019-05-10 17:13:43 +00:00
int structsize(register list2 s)
{
register list1 l;
2019-05-10 17:13:43 +00:00
register int sum;
sum = 0;
2019-05-10 17:13:43 +00:00
while (s != 0)
{
l = s->l2list->l1next;
2019-05-10 17:13:43 +00:00
while (l != 0)
{
sum++;
l = l->l1next;
}
s = s->l2next;
}
2019-05-10 17:13:43 +00:00
return (sum);
}
static int isasc(int c)
{
if ((c >= 0 && c <= 0177))
return 1;
return 0;
}
2019-05-10 17:13:43 +00:00
list2 lookstruct(list2 ll)
{
list3 l3;
2019-05-10 17:13:43 +00:00
list2 l21, l22;
list1 l11, l12;
for (l3 = structpool; l3 != 0; l3 = l3->l3next)
{
for (l21 = l3->l3list, l22 = ll; l21 != 0 && l22 != 0; l21 =
l21->l2next, l22 = l22->l2next)
{
for (l11 = l21->l2list, l12 = l22->l2list;
l11 != 0 && l12 != 0
&& strcmp(l11->l1name, l12->l1name) == 0;
l11 = l11->l1next, l12 = l12->l1next)
;
2019-05-10 17:13:43 +00:00
if (l11 != 0 || l12 != 0)
goto contin;
}
2019-05-10 17:13:43 +00:00
if (l21 == 0 && l22 == 0)
return (l3->l3list);
contin: ;
}
l3 = (list3) myalloc(sizeof(struct list3str));
2019-05-10 17:13:43 +00:00
l3->l3next = structpool;
l3->l3list = ll;
structpool = l3;
return (ll);
}
2019-05-10 17:13:43 +00:00
int instno(inst_t inst)
{
register int i, j;
2019-05-10 17:13:43 +00:00
for (i = 1; i < narinstance; i++)
{
if (arinstance[i].in_which != inst.in_which)
continue;
2019-05-10 17:13:43 +00:00
for (j = 0; j < TOKENSIZE; j++)
if (arinstance[i].in_info[j] != inst.in_info[j])
goto cont;
2019-05-10 17:13:43 +00:00
return (i);
cont: ;
}
2019-05-10 17:13:43 +00:00
chktabsiz(narinstance, MAXINSTANCE, "Instance table");
arinstance[narinstance] = inst;
2019-05-10 17:13:43 +00:00
return (narinstance++);
}
2019-05-10 17:13:43 +00:00
string scopy(string s)
{
register string t;
2019-05-10 17:13:43 +00:00
t = (char *) myalloc(strlen(s) + 1);
strcpy(t, s);
return (t);
}
2019-05-10 17:13:43 +00:00
int strlookup(string s)
{
register int i;
2019-05-10 17:13:43 +00:00
for (i = 0; i < ncodestrings; i++)
if (strcmp(s, codestrings[i]) == 0)
return (i);
chktabsiz(ncodestrings, MAXSTRINGS, "string table");
codestrings[ncodestrings] = scopy(s);
2019-05-10 17:13:43 +00:00
return (ncodestrings++);
}
2019-05-10 17:13:43 +00:00
int stringno(register string s)
{
char buf[256];
2019-05-10 17:13:43 +00:00
register char *p = buf;
while (*s != 0)
switch (*s)
{
default:
*p++ = *s++;
continue;
2019-05-10 17:13:43 +00:00
case '$':
s++;
2019-05-10 17:13:43 +00:00
switch (*s)
{
default:
yyerror("Bad character after $ in codestring");
case '$':
*p++ = *s++;
continue;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
*p++ = argtyp(patmnem[*s - '0']) == TYPINT ?
PR_EMINT : PR_EMSTR;
*p++ = *s++ - '0';
continue;
}
case '%':
s++;
if (*s != '[')
{
if (*s == '%')
{
*p++ = *s++;
continue;
}
else
yyerror("Bad character following %% in codestring");
}
else
s++;
2019-05-10 17:13:43 +00:00
if (isdigit(*s))
{
int num;
num = *s++ - '0';
if (num < 1 || num > tokpatlen)
yyerror("Number within %[] out of range");
if (*s == ']')
{
s++;
*p++ = PR_TOK;
*p++ = num;
}
else if (*s++ != '.')
yyerror(
"Bad character following %%[digit in codestring");
else
{
char field[256];
register char *f = field;
int type, offset;
while (*s != ']' && *s != 0)
*f++ = *s++;
*f++ = 0;
if (*s != ']')
yyerror(
"Unterminated %[] construction in codestring");
else
s++;
if (isdigit(field[0]))
{
chkregexp(pattokexp[num]);
*p++ = PR_SUBREG;
*p++ = num;
*p++ = atoi(field);
}
else
{
offset = findstructel(pattokexp[num], field, &type);
*p++ = PR_TOKFLD;
*p++ = num;
*p++ = offset;
}
}
}
2019-05-10 17:13:43 +00:00
else if (*s >= 'a' && *s < 'a' + nallreg)
{
int reg, subreg;
reg = *s++ - 'a' + 1;
if (*s == ']')
subreg = 255;
else
{
if (*s != '.')
yyerror(
"Bad character following %%[x in codestring");
s++;
if (!isdigit(*s))
yyerror(
"Bad character following %%[x. in codestring");
subreg = *s - '0';
s++;
if (*s != ']')
yyerror(
"Bad character following %%[x.y in codestring");
}
s++;
*p++ = PR_ALLREG;
*p++ = reg;
*p++ = subreg;
}
else
yyerror("Bad character following %%[ in codestring");
}
*p++ = 0;
2019-05-10 17:13:43 +00:00
return (strlookup(buf));
}
2019-05-10 17:13:43 +00:00
void tabovf(string tablename)
{
char buf[256];
2019-05-10 17:13:43 +00:00
sprintf(buf, "%s overflow", tablename);
yyerror(buf);
2019-05-10 17:13:43 +00:00
exit(EXIT_FAILURE);
}
2019-05-10 17:13:43 +00:00
int main(int argc, char *argv[])
{
2019-05-10 17:13:43 +00:00
while (--argc)
{
++argv;
2019-05-10 17:13:43 +00:00
if (argv[0][0] == '-')
{
switch (argv[0][1])
{
case 'h':
hname = &argv[0][2];
break;
case 'c':
cname = &argv[0][2];
break;
default:
fprintf(stderr, "Bad flag %s\n", argv[0]);
break;
}
2019-05-10 17:13:43 +00:00
}
else
{
iname = argv[0];
}
}
inithash();
initio();
inittables();
yyparse();
2019-05-10 17:13:43 +00:00
if (nerrors == 0)
{
compueq();
hashpatterns();
finishio();
verbose();
}
debug();
exit(nerrors);
}
2019-05-10 17:13:43 +00:00
int lookup(int comm, int operator, int lnode, int rnode)
{
register node_p p;
2019-05-10 17:13:43 +00:00
for (p = nodes + 1; p < lastnode; p++)
{
if (p->ex_operator != operator)
continue;
2019-05-10 17:13:43 +00:00
if (!((p->ex_lnode == lnode && p->ex_rnode == rnode)
|| (comm && p->ex_lnode == rnode && p->ex_rnode == lnode)))
continue;
2019-05-10 17:13:43 +00:00
return (p - nodes);
}
if (lastnode >= &nodes[MAXNODES])
yyerror("node table overflow");
lastnode++;
p->ex_operator = operator;
p->ex_lnode = lnode;
p->ex_rnode = rnode;
2019-05-10 17:13:43 +00:00
return (p - nodes);
}
2019-05-10 17:13:43 +00:00
static void compueq(void)
{
register int i, j;
2019-05-10 17:13:43 +00:00
for (i = 1; i < nmachregs; i++)
{
for (j = 1; j < i; j++)
if (eqregclass(i, j))
{
stregclass[i] = stregclass[j];
break;
}
2019-05-10 17:13:43 +00:00
if (j == i)
stregclass[i] = nregclasses++;
}
}
2019-05-10 17:13:43 +00:00
static int eqregclass(int r1, int r2)
{
register reginfo rp1, rp2;
register int i;
short regbits[(MAXREGS + 15) >> 4];
int member;
2019-05-10 17:13:43 +00:00
rp1 = machregs[r1];
rp2 = machregs[r2];
for (i = 0; i < ((nprops + 15) >> 4); i++)
if (rp1->rprop[i] != rp2->rprop[i])
2019-05-10 17:13:43 +00:00
return (0);
for (i = 0; i < ((MAXREGS + 15) >> 4); i++)
regbits[i] = 0;
2019-05-10 17:13:43 +00:00
for (i = 0; i < maxmembers; i++)
{
if ((member = rp1->rmembers[i]))
regbits[member >> 4] |= (1 << (member & 017));
}
2019-05-10 17:13:43 +00:00
for (i = 0; i < maxmembers; i++)
{
member = rp2->rmembers[i];
2019-05-10 17:13:43 +00:00
if (regbits[member >> 4] & (1 << (member & 017)))
return (0);
}
2019-05-10 17:13:43 +00:00
return (1);
}
2019-05-10 17:13:43 +00:00
unsigned hash(register string name)
{
register unsigned sum;
2019-05-10 17:13:43 +00:00
register int i;
2019-05-10 17:13:43 +00:00
for (sum = i = 0; *name; i += 3)
sum ^= (*name++) << (i & 07);
return (sum);
}
2019-05-10 17:13:43 +00:00
ident_p ilookup(string name, int enterf)
{
register ident_p p, *pp;
2019-05-10 17:13:43 +00:00
pp = &identtab[hash(name) % ITABSIZE];
while (*pp != 0)
{
if (strcmp((*pp)->i_name, name) == 0)
{
if (enterf != ENTER)
2019-05-10 17:13:43 +00:00
return (*pp);
else
yyerror("Multiply defined symbol");
2019-05-10 17:13:43 +00:00
}
pp = &(*pp)->i_next;
}
if (enterf == LOOKUP)
yyerror("Undefined symbol");
if (enterf == JUSTLOOKING)
2019-05-10 17:13:43 +00:00
return (0);
p = *pp = (ident_p) myalloc(sizeof(ident_t));
p->i_name = name;
p->i_next = 0;
p->i_type = 0;
2019-05-10 17:13:43 +00:00
return (p);
}
2019-05-10 17:13:43 +00:00
static void initio(void)
{
2019-05-10 17:13:43 +00:00
if (iname != 0 && freopen(iname, "r", stdin) == NULL)
{
fprintf(stderr, "Can't open %s\n", iname);
exit(-1);
}
2019-05-10 17:13:43 +00:00
if ((cfile = fopen(cname, "w")) == NULL)
{
fprintf(stderr, "Can't create %s\n", cname);
exit(-1);
}
2019-05-10 17:13:43 +00:00
if ((hfile = fopen(hname, "w")) == NULL)
{
fprintf(stderr, "Can't create %s\n", hname);
exit(-1);
}
2019-05-10 17:13:43 +00:00
fprintf(cfile, "#include \"param.h\"\n");
fprintf(cfile, "#include \"tables.h\"\n");
fprintf(cfile, "#include \"types.h\"\n");
fprintf(cfile, "#include <cg_pattern.h>\n");
fprintf(cfile, "#include \"data.h\"\n");
fprintf(cfile, "\nbyte coderules[] = {\n");
patbyte(0);
}
2019-05-10 17:13:43 +00:00
int exprlookup(set_t sett)
{
register int i, j, ok;
2019-05-10 17:13:43 +00:00
for (i = 0; i < nmachsets; i++)
{
ok = (sett.set_size == machsets[i].set_size);
for (j = 0; j < SETSIZE; j++)
{
if (sett.set_val[j] == machsets[i].set_val[j])
continue;
2019-05-10 17:13:43 +00:00
ok = 0;
break;
}
if (ok)
2019-05-10 17:13:43 +00:00
return (i);
}
2019-05-10 17:13:43 +00:00
chktabsiz(nmachsets, MAXSETS, "Expression table");
machsets[nmachsets] = sett;
2019-05-10 17:13:43 +00:00
return (nmachsets++);
}
2019-05-10 17:13:43 +00:00
static void inittables(void)
{
register reginfo r;
2019-05-10 17:13:43 +00:00
register int i;
inst_t inst;
set_t sett;
2019-05-10 17:13:43 +00:00
nodes[0].ex_operator = EX_CON;
nodes[0].ex_lnode = 0;
nodes[0].ex_rnode = 0;
cocopropno = nprops++;
r = (reginfo) myalloc(sizeof(struct reginfo));
r->rname = "cc reg";
r->rrepr = "CC";
r->rsize = -1;
2019-05-10 17:13:43 +00:00
r->rregvar = -1;
for (i = 0; i < MAXMEMBERS; i++)
r->rmembers[i] = 0;
2019-05-10 17:13:43 +00:00
for (i = 0; i < PROPSETSIZE; i++)
r->rprop[i] = 0;
2019-05-10 17:13:43 +00:00
r->rprop[cocopropno >> 4] |= (1 << (cocopropno & 017));
chktabsiz(nmachregs, MAXREGS, "Register table");
machregs[nmachregs++] = r;
inst.in_which = IN_RIDENT;
2019-05-10 17:13:43 +00:00
inst.in_info[0] = nmachregs - 1;
for (i = 1; i < TOKENSIZE; i++)
inst.in_info[i] = 0;
ccinstanceno = instno(inst);
ccregexpr = lookup(0, EX_REG, nmachregs - 1, 0);
sett.set_size = 0;
for (i = 0; i < SETSIZE; i++)
sett.set_val[i] = 0;
sett.set_val[nmachregs >> 4] |= (01 << (nmachregs & 017));
cocosetno = exprlookup(sett);
}
static void outregs(void)
{
register int i, j, k;
static short rset[(MAXREGS + 15) >> 4];
int t, ready;
fprintf(cfile, "char stregclass[] = {\n");
for (i = 0; i < nmachregs; i++)
fprintf(cfile, "\t%d,\n", stregclass[i]);
fprintf(cfile, "};\n\nstruct reginfo machregs[] = {\n{0},\n");
for (i = 1; i < nmachregs; i++)
{
fprintf(cfile, "{%d,%d", strlookup(machregs[i]->rrepr),
machregs[i]->rsize);
if (maxmembers != 0)
{
fprintf(cfile, ",{");
for (j = 0; j < maxmembers; j++)
fprintf(cfile, "%d,", machregs[i]->rmembers[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.
*/
2019-05-10 17:13:43 +00:00
for (j = 0; j < ((MAXREGS + 15) >> 4); j++)
rset[j] = 0;
rset[i >> 4] |= (1 << (i & 017));
do
{
ready = 1;
for (j = 1; j < nmachregs; j++)
if (rset[j >> 4] & (1 << (j & 017)))
for (k = 0; k < maxmembers; k++)
if ((t = machregs[j]->rmembers[k]) != 0)
{
if ((rset[t >> 4] & (1 << (t & 017))) == 0)
ready = 0;
rset[t >> 4] |= (1 << (t & 017));
}
} while (!ready);
2019-05-10 17:13:43 +00:00
do
{
ready = 1;
for (j = 1; j < nmachregs; j++)
for (k = 0; k < maxmembers; k++)
if ((t = machregs[j]->rmembers[k]) != 0)
if (rset[t >> 4] & (1 << (t & 017)))
{
if ((rset[j >> 4] & (1 << (j & 017))) == 0)
ready = 0;
rset[j >> 4] |= (1 << (j & 017));
}
} while (!ready);
2019-05-10 17:13:43 +00:00
fprintf(cfile, "},{");
for (j = 0; j < ((nmachregs + 15) >> 4); j++)
fprintf(cfile, "%d,", rset[j]);
fprintf(cfile, "}");
}
2019-05-10 17:13:43 +00:00
if (machregs[i]->rregvar >= 0)
fprintf(cfile, ",1");
fprintf(cfile, "},\n");
}
2019-05-10 17:13:43 +00:00
fprintf(cfile, "};\n\n");
}
2019-05-10 17:13:43 +00:00
static void finishio(void)
{
register int i;
register node_p np;
int j;
int setsize;
register move_p mp;
2019-05-10 17:13:43 +00:00
fprintf(cfile, "};\n\n");
if (wsize > 0)
fprintf(hfile, "#define TEM_WSIZE %d\n", wsize);
else
yyerror("Wordsize undefined");
2019-05-10 17:13:43 +00:00
if (psize > 0)
fprintf(hfile, "#define TEM_PSIZE %d\n", psize);
else
yyerror("Pointersize undefined");
2019-05-10 17:13:43 +00:00
if (bsize >= 0)
fprintf(hfile, "#define TEM_BSIZE %d\n", bsize);
else
yyerror("EM_BSIZE undefined");
2019-05-10 17:13:43 +00:00
if (fmt != 0)
fprintf(hfile, "#define WRD_FMT \"%s\"\n", fmt);
fprintf(hfile, "#define MAXALLREG %d\n", maxallreg);
setsize = (nmachregs + 1 + nmachtokens + 15) >> 4;
fprintf(hfile, "#define SETSIZE %d\n", setsize);
fprintf(hfile, "#define NPROPS %d\n", nprops);
fprintf(hfile, "#define NREGS %d\n", nmachregs);
fprintf(hfile, "#define REGSETSIZE %d\n", (nmachregs + 15) >> 4);
fprintf(hfile, "#define TOKENSIZE %d\n", maxtokensize);
fprintf(hfile, "#define MAXMEMBERS %d\n", maxmembers);
fprintf(hfile, "#define LONGESTPATTERN %d\n", maxempatlen);
fprintf(hfile, "#define MAXRULE %d\n", maxrule);
fprintf(hfile, "#define NMOVES %d\n", nmoves);
fprintf(hfile, "#define NC1 %d\n", nc1);
if (nc2)
{
assert(maxsplit != 0);
fprintf(hfile, "#define NC2 %d\n", nc2);
fprintf(hfile, "#define MAXSPLIT %d\n", maxsplit);
}
fprintf(hfile, "#define NC3 %d\n", nc3);
outregs();
2019-05-10 17:13:43 +00:00
fprintf(cfile, "tkdef_t tokens[] = {\n");
for (i = 0; i < nmachtokens; i++)
{
fprintf(cfile, "{%d,{%d,%d},{", machtokens[i].t_size,
machtokens[i].t_cost.c_size, machtokens[i].t_cost.c_time);
for (j = 0; j < maxtokensize; j++)
fprintf(cfile, "%d,", machtokens[i].t_fields[j].t_type);
fprintf(cfile, "},%d},\n", machtokens[i].t_format);
}
fprintf(cfile, "};\n\nnode_t enodes[] = {\n");
for (np = nodes; np < lastnode; np++)
fprintf(cfile, "{%d,%d,%d},\n", np->ex_operator, np->ex_lnode,
np->ex_rnode);
2019-05-10 17:13:43 +00:00
fprintf(cfile, "};\n\nstring codestrings[] = {\n");
for (i = 0; i < ncodestrings; i++)
{
register char *p;
2019-05-10 17:13:43 +00:00
p = codestrings[i];
fprintf(cfile, "\t\"");
while (*p)
{
register int c = (*p) & BMASK;
2019-05-10 17:13:43 +00:00
if (!isasc(c) || iscntrl(c))
{
/* The next line used to have (c>>6)&03,
2019-05-10 17:13:43 +00:00
but this triggered a bug in GCC 2.4.5
on SPARC.
*/
fprintf(cfile, "\\%c%c%c", ((*p >> 6) & 03) + '0',
((c >> 3) & 07) + '0', (c & 07) + '0');
}
2019-05-10 17:13:43 +00:00
else
putc(c, cfile);
p++;
}
2019-05-10 17:13:43 +00:00
fprintf(cfile, "\",\n");
}
fprintf(cfile, "};\n\nset_t machsets[] = {\n");
for (i = 0; i < nmachsets; i++)
{
fprintf(cfile, "{%d,{", machsets[i].set_size);
for (j = 0; j < setsize; j++)
fprintf(cfile, "0%o,", machsets[i].set_val[j] & 0xFFFF);
fprintf(cfile, "}},\n");
}
fprintf(cfile, "};\n\ninst_t tokeninstances[] = {\n");
for (i = 0; i < narinstance; i++)
{
fprintf(cfile, "{ %d, {", arinstance[i].in_which);
for (j = 0; j <= maxtokensize; j++)
fprintf(cfile, "%d,", arinstance[i].in_info[j]);
fprintf(cfile, "}},\n");
}
fprintf(cfile, "};\n\nmove_t moves[] = {\n");
for (i = 0; i < nmoves; i++)
{
mp = &machmoves[i];
2019-05-10 17:13:43 +00:00
fprintf(cfile, "{%d,%d,%d,%d,%d,{%d,%d}},\n", mp->m_set1, mp->m_expr1,
mp->m_set2, mp->m_expr2, mp->m_cindex, mp->m_cost.c_size,
mp->m_cost.c_time);
}
fprintf(cfile, "};\n\nbyte pattern[] = {\n");
for (i = 0; i < npatbytes; i++)
{
fprintf(cfile, "%3d,", pattern[i] & BMASK);
if ((i % 10) == 9)
fprintf(cfile, "\n");
}
fprintf(cfile, "\n};\n\nint pathash[256] = {\n");
for (i = 0; i < 256; i++)
{
fprintf(cfile, "%6d,", pathash[i]);
if ((i & 07) == 07)
fprintf(cfile, "\n");
}
fprintf(cfile, "};\n\nc1_t c1coercs[] = {\n");
for (i = 0; i < nc1; i++)
fprintf(cfile, "{%d,%d,%d,%d,{%d,%d}},\n", c1coercs[i].c1_texpno,
c1coercs[i].c1_expr, c1coercs[i].c1_prop, c1coercs[i].c1_codep,
c1coercs[i].c1_cost.c_size, c1coercs[i].c1_cost.c_time);
if (nc2)
2019-05-10 17:13:43 +00:00
fprintf(cfile, "};\n\nc2_t c2coercs[] = {\n");
for (i = 0; i < nc2; i++)
{
fprintf(cfile, "{%d,%d,{", c2coercs[i].c2_texpno,
c2coercs[i].c2_nsplit);
for (j = 0; j < maxsplit; j++)
fprintf(cfile, "%d,", c2coercs[i].c2_repl[j]);
fprintf(cfile, "},%d},\n", c2coercs[i].c2_codep);
}
fprintf(cfile, "};\n\nc3_t c3coercs[] = {\n");
for (i = 0; i < nc3; i++)
fprintf(cfile, "{%d,%d,%d,%d},\n", c3coercs[i].c3_texpno,
c3coercs[i].c3_prop, c3coercs[i].c3_repl, c3coercs[i].c3_codep);
fprintf(cfile, "};\n\n");
for (i = 0; i < nprops; i++)
{
fprintf(cfile, "struct reginfo *rlist%d[] = {\n", i);
for (j = 2; j <= nmachregs; j++)
{
if (machregs[j - 1]->rregvar < 0
&& (machprops[i].propset.set_val[j >> 4] & (1 << (j & 017))))
fprintf(cfile, "\t&machregs[%d],\n", j - 1);
}
2019-05-10 17:13:43 +00:00
fprintf(cfile, "\t0\n};\n");
}
2019-05-10 17:13:43 +00:00
fprintf(cfile, "struct reginfo **reglist[] = {\n");
for (i = 0; i < nprops; i++)
{
fprintf(cfile, "\trlist%d,\n", i);
}
2019-05-10 17:13:43 +00:00
fprintf(cfile, "};\n");
fprintf(cfile, "unsigned cc1 = %u;\n", cc1);
fprintf(cfile, "unsigned cc2 = %u;\n", cc2);
fprintf(cfile, "unsigned cc3 = %u;\n", cc3);
fprintf(cfile, "unsigned cc4 = %u;\n", cc4);
if (rvused)
outregvar();
}
2019-05-10 17:13:43 +00:00
static void outregvar(void)
{
register int i, j;
fprintf(hfile, "#define REGVARS\n");
fprintf(cfile, "#include \"regvar.h\"\n");
fprintf(cfile, "int nregvar[4] = { ");
for (i = 0; i < 4; i++)
fprintf(cfile, "%d, ", nregvar[i]);
fprintf(cfile, "};\n");
for (i = 0; i < 4; i++)
if (nregvar[i] > 0)
fprintf(cfile, "struct regassigned ratar%d[%d];\n", i, nregvar[i]);
for (i = 0; i < 4; i++)
if (nregvar[i] > 0)
{
fprintf(cfile, "int rvtar%d[] = {", i);
for (j = 0; j < nregvar[i]; j++)
fprintf(cfile, "%d,", rvnumbers[i][j]);
fprintf(cfile, "};\n");
}
fprintf(cfile, "\nint *rvnumbers[] = {\n");
for (i = 0; i < 4; i++)
if (nregvar[i] > 0)
fprintf(cfile, "\trvtar%d,\n", i);
else
2019-05-10 17:13:43 +00:00
fprintf(cfile, "\t0,\n");
fprintf(cfile, "};\n\nstruct regassigned *regassigned[] = {\n");
for (i = 0; i < 4; i++)
if (nregvar[i] > 0)
fprintf(cfile, "\tratar%d,\n", i);
else
2019-05-10 17:13:43 +00:00
fprintf(cfile, "\t0,\n");
fprintf(cfile, "};\n");
}
2019-05-10 17:13:43 +00:00
static void verbose(void)
{
fprintf(stderr, "Codebytes %d\n", codebytes);
fprintf(stderr, "Registers %d(%d)\n", nmachregs, MAXREGS);
fprintf(stderr, "Properties %d(%d)\n", nprops, MAXPROPS);
fprintf(stderr, "Tokens %d(%d)\n", nmachtokens, MAXTOKENS);
fprintf(stderr, "Sets %d(%d)\n", nmachsets, MAXSETS);
fprintf(stderr, "Tokeninstances %d(%d)\n", narinstance, MAXINSTANCE);
fprintf(stderr, "Strings %d(%d)\n", ncodestrings, MAXSTRINGS);
fprintf(stderr, "Enodes %d(%d)\n", lastnode - nodes, MAXNODES);
fprintf(stderr, "Patbytes %d(%d)\n", npatbytes, MAXPATTERN);
}
2019-05-10 17:13:43 +00:00
void inbetween(void)
{
register ident_p ip;
2019-05-10 17:13:43 +00:00
register int i, j;
register move_p mp;
2019-05-10 17:13:43 +00:00
lookident = 1; /* for lexical analysis */
2019-05-10 17:13:43 +00:00
chktabsiz(nmachsets + 1, MAXSETS, "Expressiontable");
for (i = 0; i < SETSIZE; i++)
machsets[nmachsets].set_val[i] = (short)0xFFFF;
machsets[nmachsets].set_val[0] &= ~1;
machsets[nmachsets].set_size = 0;
2019-05-10 17:13:43 +00:00
ip = ilookup("SCRATCH", ENTER);
ip->i_type = IEXP;
ip->i_i.i_expno = nmachsets++;
2019-05-10 17:13:43 +00:00
for (i = 0; i < SETSIZE; i++)
machsets[nmachsets].set_val[i] = (short)0xFFFF;
machsets[nmachsets].set_size = 0;
2019-05-10 17:13:43 +00:00
ip = ilookup("ALL", ENTER);
ip->i_type = IEXP;
allexpno = ip->i_i.i_expno = nmachsets++;
mp = &machmoves[nmoves++];
mp->m_set1 = cocosetno;
mp->m_expr1 = 0;
2019-05-10 17:13:43 +00:00
mp->m_set2 = nmachsets - 1;
mp->m_expr2 = 0;
mp->m_cindex = 0;
mp->m_cost.c_size = 0;
mp->m_cost.c_time = 0;
/*
* Create sets of registers per property
*/
2019-05-10 17:13:43 +00:00
for (i = 0; i < nprops; i++)
{
short *sp = machprops[i].propset.set_val;
sp[0] |= 1;
2019-05-10 17:13:43 +00:00
for (j = 2; j <= nmachregs; j++)
if (machregs[j - 1]->rprop[i >> 4] & (1 << (i & 017)))
sp[j >> 4] |= (1 << (j & 017));
}
}
2019-05-10 17:13:43 +00:00
int formconversion(register char *p, register token_p tp)
{
char buf[256];
2019-05-10 17:13:43 +00:00
register char *q = buf;
char field[256];
register char *f;
int i;
2019-05-10 17:13:43 +00:00
if (p == 0)
return (0);
while (*p)
switch (*p)
{
default:
*q++ = *p++;
continue;
case '%':
p++;
if (*p == '%')
{
*q++ = *p++;
continue;
}
if (*p == '[')
p++;
else
yyerror("Bad character after % in format");
f = field;
while (*p != 0 && *p != ']')
*f++ = *p++;
*f++ = 0;
if (*p == ']')
p++;
else
yyerror("Unterminated %[] construct in format");
for (i = 0; i < TOKENSIZE - 1; i++)
if (strcmp(field, tp->t_fields[i].t_sname) == 0)
break;
if (i == TOKENSIZE - 1)
yyerror("Unknown field in %[] construct in format");
*q++ = i + 1;
}
*q++ = 0;
2019-05-10 17:13:43 +00:00
return (strlookup(buf));
}
2019-05-10 17:13:43 +00:00
void setfields(register token_p tp, string format)
{
register int i;
list2 ll;
register list1 l;
int type;
2019-05-10 17:13:43 +00:00
for (i = 0; i < TOKENSIZE - 1; i++)
tp->t_fields[i].t_type = 0;
2019-05-10 17:13:43 +00:00
i = 0;
for (ll = tp->t_struct; ll != 0; ll = ll->l2next)
{
l = ll->l2list;
if (strcmp(l->l1name, "REGISTER") == 0)
type = TYPREG;
2019-05-10 17:13:43 +00:00
else if (strcmp(l->l1name, "INT") == 0)
type = TYPINT;
2019-05-10 17:13:43 +00:00
else
type = TYPSTR;
for (l = l->l1next; l != 0; l = l->l1next)
{
tp->t_fields[i].t_type = type;
tp->t_fields[i].t_sname = l->l1name;
i++;
}
}
if (format != 0)
2019-05-10 17:13:43 +00:00
tp->t_format = formconversion(format, tp);
else
tp->t_format = -1;
}
2019-05-10 17:13:43 +00:00
void chkregexp(int number)
{
register int i;
2019-05-10 17:13:43 +00:00
for (i = nmachregs + 1; i < nmachregs + 1 + nmachtokens; i++)
if (machsets[number].set_val[i >> 4] & (01 << (i & 017)))
yyerror("No tokens allowed in this set");
}
2019-05-10 17:13:43 +00:00
int findstructel(int number, string name, int *t)
{
register int i;
register token_p tp;
register list2 structdecl;
int offset;
2019-05-10 17:13:43 +00:00
for (i = 1; i <= nmachregs; i++)
if (machsets[number].set_val[i >> 4] & (01 << (i & 017)))
yyerror("No registers allowed in this set");
structdecl = 0;
2019-05-10 17:13:43 +00:00
for (i = nmachregs + 1; i < nmachregs + 1 + nmachtokens; i++)
{
if (machsets[number].set_val[i >> 4] & (01 << (i & 017)))
{
if (structdecl == 0)
{
structdecl = machtokens[i - (nmachregs + 1)].t_struct;
tp = &machtokens[i - (nmachregs + 1)];
}
else if (structdecl != machtokens[i - (nmachregs + 1)].t_struct)
yyerror("Multiple structs in this set");
}
}
2019-05-10 17:13:43 +00:00
if (structdecl == 0)
{
yyerror("No structs in this set");
2019-05-10 17:13:43 +00:00
return (0);
}
2019-05-10 17:13:43 +00:00
for (offset = 0; offset < TOKENSIZE - 1; offset++)
if (tp->t_fields[offset].t_type != 0
&& strcmp(tp->t_fields[offset].t_sname, name) == 0)
{
*t = tp->t_fields[offset].t_type;
2019-05-10 17:13:43 +00:00
return (offset + 1);
}
yyerror("No such field in this struct");
2019-05-10 17:13:43 +00:00
return (0);
}
extern char em_flag[];
2019-05-10 17:13:43 +00:00
int argtyp(int mn)
{
switch (em_flag[mn - sp_fmnem] & EM_PAR)
{
case PAR_W:
case PAR_S:
case PAR_Z:
case PAR_O:
case PAR_N:
case PAR_L:
case PAR_F:
case PAR_R:
case PAR_C:
return (TYPINT);
default:
return (TYPSTR);
}
}
2019-05-10 17:13:43 +00:00
int commontype(expr_t e1, expr_t e2)
{
if (e1.expr_typ != e2.expr_typ)
yyerror("Type incompatibility");
2019-05-10 17:13:43 +00:00
return (e1.expr_typ);
}
extern char em_mnem[][4];
#define HASHSIZE (2*(sp_lmnem-sp_fmnem))
2019-05-10 17:13:43 +00:00
struct hashmnem
{
char h_name[3];
byte h_value;
} hashmnem[HASHSIZE];
2019-05-10 17:13:43 +00:00
void inithash(void)
{
register int i;
2019-05-10 17:13:43 +00:00
for (i = 0; i <= sp_lmnem - sp_fmnem; i++)
enter(em_mnem[i], i + sp_fmnem);
}
2019-05-10 17:13:43 +00:00
void enter(char *name, int value)
{
register unsigned h;
2019-05-10 17:13:43 +00:00
h = hash(name) % HASHSIZE;
while (hashmnem[h].h_name[0] != 0)
2019-05-10 17:13:43 +00:00
h = (h + 1) % HASHSIZE;
strncpy(hashmnem[h].h_name, name, 3);
hashmnem[h].h_value = value;
}
2019-05-10 17:13:43 +00:00
int mlookup(char *name)
{
register unsigned int h;
2019-05-10 17:13:43 +00:00
h = hash(name) % HASHSIZE;
while (strncmp(hashmnem[h].h_name, name, 3) != 0
&& hashmnem[h].h_name[0] != 0)
h = (h + 1) % HASHSIZE;
return (hashmnem[h].h_value & BMASK); /* 0 if not found */
}
2019-05-10 17:13:43 +00:00
void hashpatterns(void)
{
short index;
2019-05-10 17:13:43 +00:00
register byte *bp, *tp;
register short i;
unsigned short hashvalue;
int patlen;
index = prevind;
2019-05-10 17:13:43 +00:00
while (index != 0)
{
bp = &pattern[index];
tp = &bp[PO_MATCH];
2019-05-10 17:13:43 +00:00
i = *tp++ & BMASK;
if (i == BMASK)
{
i = *tp++ & BMASK;
i |= (*tp++ & BMASK) << BSHIFT;
}
patlen = i;
hashvalue = 0;
2019-05-10 17:13:43 +00:00
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);
2019-05-10 17:13:43 +00:00
i = index;
index = (bp[PO_NEXT] & BMASK) | (bp[PO_NEXT + 1] << BSHIFT);
bp[PO_HASH] = hashvalue >> BSHIFT;
hashvalue &= BMASK;
2019-05-10 17:13:43 +00:00
bp[PO_NEXT] = pathash[hashvalue] & BMASK;
bp[PO_NEXT + 1] = pathash[hashvalue] >> BSHIFT;
pathash[hashvalue] = i;
}
}
2019-05-10 17:13:43 +00:00
static void debug(void)
{
register int i, j;
2019-05-10 17:13:43 +00:00
for (i = 0; i < ITABSIZE; i++)
{
register ident_p ip;
2019-05-10 17:13:43 +00:00
for (ip = identtab[i]; ip != 0; ip = ip->i_next)
printf("%-14s %1d %3d\n", ip->i_name, ip->i_type, ip->i_i.i_regno);
}
2019-05-10 17:13:43 +00:00
for (i = 2; i < nmachregs; i++)
{
register reginfo rp;
2019-05-10 17:13:43 +00:00
rp = machregs[i];
printf("%s = (\"%s\", %d", rp->rname, rp->rrepr, rp->rsize);
for (j = 0; j < MAXMEMBERS; j++)
if (rp->rmembers[j] != 0)
printf(", %s", machregs[rp->rmembers[j]]->rname);
printf(")");
2019-05-10 17:13:43 +00:00
for (j = 0; j < nprops; j++)
if (rp->rprop[j >> 4] & (1 << (j & 017)))
printf(", %s", machprops[j].propname->i_name);
printf(".\n");
}
}
2019-05-10 17:13:43 +00:00
void out(int n)
{
2019-05-10 17:13:43 +00:00
assert(n >= 0);
if (n < 128)
outbyte(n);
2019-05-10 17:13:43 +00:00
else
{
outbyte(n / 256 + 128);
outbyte(n % 256);
}
}
2019-05-10 17:13:43 +00:00
void outbyte(int n)
{
2019-05-10 17:13:43 +00:00
fprintf(cfile, "%d, ", n & BMASK);
codebytes++;
}
2019-05-10 17:13:43 +00:00
void pat(int n)
{
2019-05-10 17:13:43 +00:00
assert(n >= 0);
if (n < 128)
patbyte(n);
2019-05-10 17:13:43 +00:00
else
{
patbyte(n / 256 + 128);
patbyte(n % 256);
}
}
2019-05-10 17:13:43 +00:00
void patshort(int n)
{
2019-05-10 17:13:43 +00:00
patbyte(n & BMASK);
patbyte(n >> BSHIFT);
}
2019-05-10 17:13:43 +00:00
void patbyte(int n)
{
chktabsiz(npatbytes, MAXPATTERN, "Pattern table");
pattern[npatbytes++] = n;
}
2019-05-10 17:13:43 +00:00
int max(int a, int b)
{
if (a > b)
return (a);
return (b);
}
2019-05-10 17:13:43 +00:00
int yywrap(void)
{
return 1;
}