ack/modules/src/em_opt/outputdfa.c

514 lines
11 KiB
C
Raw Normal View History

1987-01-15 18:12:26 +00:00
#ifndef NORCSID
static char rcsidp5[] = "$Header$";
1987-01-15 18:12:26 +00:00
#endif
#include "parser.h"
#include "Lpars.h"
FILE *ofile;
1987-01-15 18:12:26 +00:00
outputnopt()
{
openofile("dfa.c");
outdfa();
installofile();
openofile("trans.c");
outdotrans();
installofile();
openofile("incalls.r");
1987-01-15 18:12:26 +00:00
outputincalls();
installofile();
}
static char ofilename[80];
static char ofiletemp[80];
PRIVATE
openofile(filename)
char *filename;
{
char *strcpy(), *strcat();
strcpy(ofilename,filename);
strcpy(ofiletemp,filename);
strcat(ofiletemp,".new");
if((ofile=fopen(ofiletemp,"w"))==NULL) {
fprintf(stderr,"Fatal Error: cannot open output file %s\n",ofiletemp);
sys_stop(S_EXIT);
}
}
PRIVATE
installofile()
{
/*
* if contents of newly generated ofiletemp is different
* from that of ofilename then copy over old file else
* delete newly generated file
*/
register FILE *f1, *f2;
register int c1, c2;
fclose(ofile);
if((f1 = fopen(ofiletemp,"r")) == NULL) {
fprintf(stderr,"Fatal Error: cannont reopen file %s\n",ofiletemp);
sys_stop(S_EXIT);
}
if((f2 = fopen(ofilename,"r")) == NULL) {
fclose(f1);
RENAME(ofiletemp,ofilename);
return;
}
do {
c1 = getc(f1);
c2 = getc(f2);
} while (c1 == c2 && c1 != EOF);
fclose(f1);
fclose(f2);
if (c1 != c2) {
RENAME(ofiletemp,ofilename);
}
else UNLINK(ofiletemp);
}
PRIVATE
UNLINK(x)
char *x;
{
/* Must remove the file "x" */
unlink(x); /* systemcall to remove file */
}
PRIVATE
RENAME(x,y)
char *x, *y;
{
/* Must move the file "x" to the file "y" */
unlink(y);
if(link(x,y)!=0) {
fprintf(stderr,"Cannot link to %s",y);
sys_stop(S_EXIT);
}
unlink(x);
1987-01-15 18:12:26 +00:00
}
# define MAXOPCODE 255
# define EMPTY -1
int *next, *check, *base;
unsigned currsize; /* current size of next and check arrays */
int maxpos = 0; /* highest used position in these arrayes */
PRIVATE
increase_next(size)
int size;
{
/* realloc arrays next and check so they are at least
* of size 'size'
*/
char *Realloc();
unsigned newsize = currsize;
register int i;
do {
newsize *= 2;
} while (newsize<size);
printf("Note: Extending next/check arrays from %d to %d\n",currsize,newsize);
next = (int *)Realloc(next,newsize);
check = (int *)Realloc(check,newsize);
/* clear ends of new arrays */
for(i=currsize;i<newsize;i++)
next[i] = check[i] = EMPTY;
currsize = newsize;
}
PRIVATE
store_row(state,row)
int state;
register int *row;
{
/* find a place to store row in arrays */
register b,i,o;
register int *n = next;
b=0;
for(;;) {
/* look for first possible place to store it */
for(i=0;i<MAXOPCODE;i++) {
if(row[i]) {
if((o = b+i)>currsize) increase_next(o);
if(n[o]!=EMPTY) goto nextpos;
}
}
/* found a place */
base[state]=b;
for(i=0;i<MAXOPCODE;i++)
if(row[i]) {
if((o=b+i) >maxpos) maxpos = o;
next[o] = row[i];
check[o] = state;
}
return;
nextpos:
++b;
}
}
1987-01-15 18:12:26 +00:00
PRIVATE
outdfa()
1987-01-15 18:12:26 +00:00
{
register int s,i;
register struct state *p;
int nout, ncpy, ngto;
int row[MAXOPCODE];
int numinrow;
int numentries = 0;
fprintf(ofile,"#include \"nopt.h\"\n");
fprintf(ofile,"\n");
fprintf(ofile,"int OO_maxreplacement = %d;\n", maxreplacement);
fprintf(ofile,"\n");
/* find how many entries in dfa */
for(s=0;s<=higheststate;s++)
for(p=states[s];p!=(struct state *)NULL;p=p->next)
numentries++;
/* start with next and check arrays twice this size */
currsize = 2 * numentries;
next = (int *)Malloc(currsize*sizeof(int));
check = (int *)Malloc(currsize*sizeof(int));
base = (int *)Malloc(((unsigned)(higheststate+1))*sizeof(int));
/* fill next array with EMPTY */
for(i=0;i<currsize;i++) check[i]=next[i]=EMPTY;
for(s=0;s<=higheststate;s++) {
/* empty row */
for(i=0;i<MAXOPCODE;i++) row[i]=0;
numinrow = 0;
/* fill in non zero entries */
for(p=states[s];p!=(struct state *)NULL;p=p->next) {
numinrow++;
row[p->op->id_opcode] = p->goto_state;
}
/* look for a place to store row */
if(numinrow)
store_row(s,row);
else
base[s] = EMPTY;
}
/* give some statistics on size of dfa */
printf("Number of patterns: %d\n", numpatterns);
printf("Longest pattern: %d\n", maxpattern);
printf("Longest replacement: %d\n", maxreplacement);
printf("Dfa contains %d distinct state/opcode pairs\n", numentries);
printf("Compacted using row displacement into %d entries\n",maxpos);
/* output the arrays */
fprintf(ofile,"struct dfa OO_checknext[] = {\n");
for(i=0;i<=maxpos;i++) {
fprintf(ofile,"\t/* %4d */\t",i);
fprintf(ofile,"{%4d,%4d},\n", check[i], next[i]);
}
fprintf(ofile,"};\n\n");
fprintf(ofile,"struct dfa *OO_base[] = {\n");
for(s=0;s<=higheststate;s++) {
fprintf(ofile,"\t/* %4d: ",s);
outmnems(patterns[s]);
fprintf(ofile,"*/\t");
if(base[s]==EMPTY)
fprintf(ofile,"0,\n");
else
fprintf(ofile,"&OO_checknext[%4d],\n", base[s]);
}
fprintf(ofile,"};\n\n");
fprintf(ofile,"struct dodefault OO_default[] = {\n");
for(s=0;s<=higheststate;s++) {
fprintf(ofile,"\t/* %4d: ",s);
outmnems(patterns[s]);
fprintf(ofile,"*/\t");
findfail(s,&nout,&ncpy,&ngto);
fprintf(ofile,"{%4d,%4d},\n", nout,ngto);
1987-01-15 18:12:26 +00:00
}
fprintf(ofile,"};\n\n");
1987-01-15 18:12:26 +00:00
}
PRIVATE
outmnems(l)
1987-01-15 18:12:26 +00:00
struct mnems l;
{
int i;
for(i=1;i<=l.m_len;i++)
fprintf(ofile,"%s ",l.m_elems[i-1]->op_code->id_text);
1987-01-15 18:12:26 +00:00
}
PRIVATE
outdotrans()
1987-01-15 18:12:26 +00:00
{
int s;
struct action *a;
int seennontested;
fprintf(ofile,"#include \"nopt.h\"\n\n");
/* declare all the trans functions */
for(s=0;s<=higheststate;s++) {
if(actions[s]!=(struct action *)NULL)
fprintf(ofile,"static do%dtrans();\n",s);
}
/* output the array itself */
fprintf(ofile,"\nint (*OO_ftrans[])()=\n{\n");
for(s=0;s<=higheststate;s++) {
if(actions[s]!=(struct action *)NULL)
fprintf(ofile,"\tdo%dtrans,\n",s);
else
fprintf(ofile,"\t0,\n");
}
fprintf(ofile,"};\n\n");
/* now output the functions */
for(s=0;s<=higheststate;s++) {
1987-01-15 18:12:26 +00:00
if(actions[s]!=(struct action *)NULL) {
fprintf(ofile,"\nstatic do%dtrans() {\n",s);
fprintf(ofile,"\tregister p_instr patt = OO_patternqueue;\n");
fprintf(ofile,"\t/* ");
outmnems(patterns[s]);
fprintf(ofile," */\n");
seennontested=0;
1987-01-15 18:12:26 +00:00
for(a=actions[s];a!=(struct action *)NULL;a=a->next) {
if(a->test!=(struct exp_node *)NULL) {
fprintf(ofile,"\tif(");
outexp(a->test,s);
fprintf(ofile,") {\n");
outoneaction(s,a);
fprintf(ofile,"\t\treturn;\n");
fprintf(ofile,"\t}\n");
1987-01-15 18:12:26 +00:00
}
else {
if(seennontested) {
fprintf(stderr,"parser: more than one untested action on state %d\n",s);
1987-01-15 18:12:26 +00:00
nerrors++;
}
seennontested++;
outoneaction(s,a);
1987-01-15 18:12:26 +00:00
}
}
fprintf(ofile,"}\n");
1987-01-15 18:12:26 +00:00
}
}
1987-01-15 18:12:26 +00:00
}
PRIVATE
outoneaction(s,a)
1987-01-15 18:12:26 +00:00
int s;
struct action *a;
{
fprintf(ofile,"\t\t/* -> ");
outmnems(a->replacement);
fprintf(ofile," */\n");
fprintf(ofile,"#ifdef STATS\n");
fprintf(ofile,"\t\tif(OO_wrstats) fprintf(stderr,\"%d\\n\");\n",a->linenum);
fprintf(ofile,"#endif\n");
outrepl(s,a->replacement);
findworst(patterns[s],a->replacement);
1987-01-15 18:12:26 +00:00
}
PRIVATE
outrepl(state,repl)
1987-01-15 18:12:26 +00:00
int state;
struct mnems repl;
1987-01-15 18:12:26 +00:00
{
/*
/* Contruct <repl>=r1 r2 ... rn and put on output queue.
*/
int n = repl.m_len;
int i;
1987-01-15 18:12:26 +00:00
for(i=1;i<=n;i++) {
struct mnem_elem *ri = repl.m_elems[i-1];
char *mnem = ri->op_code->id_text;
switch(ri->op_code->id_argfmt) {
case NOARG:
fprintf(ofile,"\t\tEM_mkop(GETNXTREPL(),op_%s);\n",mnem);
1987-01-15 18:12:26 +00:00
break;
case CST:
fprintf(ofile,"\t\tEM_mkcst(GETNXTREPL(),op_%s,",mnem);
fprintf(ofile,"(arith)");
outexp(ri->arg,state);
fprintf(ofile,");\n");
1987-01-15 18:12:26 +00:00
break;
case CSTOPT:
if(ri->arg) {
fprintf(ofile,"\t\tEM_mkcst(GETNXTREPL(),op_%s,",mnem);
fprintf(ofile,"(arith)");
outexp(ri->arg,state);
}
else {
fprintf(ofile,"\t\tEM_mknarg(GETNXTREPL(),op_%s);\n",mnem);
}
fprintf(ofile,");\n");
break;
1987-01-15 18:12:26 +00:00
case LAB:
fprintf(ofile,"\t\tEM_mkilb(GETNXTREPL(),op_%s,",mnem);
outexp(ri->arg,state);
fprintf(ofile,");\n");
1987-01-15 18:12:26 +00:00
break;
case DEFILB:
fprintf(ofile,"\t\tEM_mkdefilb(GETNXTREPL(),op_%s,",mnem);
outexp(ri->arg,state);
fprintf(ofile,");\n");
1987-01-15 18:12:26 +00:00
break;
case PNAM:
fprintf(ofile,"\t\tEM_mkpro(GETNXTREPL(),op_%s,",mnem);
outexp(ri->arg,state);
fprintf(ofile,");\n");
1987-01-15 18:12:26 +00:00
break;
case EXT:
fprintf(ofile,"\t\tOO_mkext(GETNXTREPL(),op_%s,",mnem);
outexp(ri->arg,state);
fprintf(ofile,");\n");
1987-01-15 18:12:26 +00:00
break;
}
}
}
PRIVATE
outexp(e,state)
1987-01-15 18:12:26 +00:00
struct exp_node *e;
int state;
{
switch(e->node_type) {
case LOGAND:
case LOGOR:
case BITAND:
case BITOR:
case XOR:
case MINUS:
case PLUS:
case TIMES:
case DIV:
case MOD:
case EQ:
case NE:
case LT:
case LE:
case GT:
case GE:
case LSHIFT:
case RSHIFT:
fprintf(ofile,"(");
outexp(e->exp_left,state);
outop(e->node_type);
outexp(e->exp_right,state);
fprintf(ofile,")");
1987-01-15 18:12:26 +00:00
break;
case NOT:
case COMP:
case UPLUS:
case UMINUS:
fprintf(ofile,"(");
outop(e->node_type);
outexp(e->exp_left,state);
fprintf(ofile,")");
1987-01-15 18:12:26 +00:00
break;
case DEFINED:
fprintf(ofile,"DEFINED(patt[%d])",e->leaf_val-1);
1987-01-15 18:12:26 +00:00
break;
case UNDEFINED:
fprintf(ofile,"!DEFINED(patt[%d])",e->leaf_val-1);
1987-01-15 18:12:26 +00:00
break;
case COMMA:
outext(e->exp_left);
fprintf(ofile,",");
fprintf(ofile,"(arith)");
outexp(e->exp_right,state);
1987-01-15 18:12:26 +00:00
break;
case SAMESIGN:
case SFIT:
case UFIT:
case ROTATE:
outop(e->node_type);
fprintf(ofile,"(arith)");
outexp(e->exp_left,state);
fprintf(ofile,",");
fprintf(ofile,"(arith)");
outexp(e->exp_right,state);
fprintf(ofile,")");
1987-01-15 18:12:26 +00:00
break;
case SAMEEXT:
case SAMENAM:
outop(e->node_type);
1987-01-15 18:12:26 +00:00
outext(e->exp_left);
fprintf(ofile,",");
outext(e->exp_right);
fprintf(ofile,")");
1987-01-15 18:12:26 +00:00
break;
case PATARG:
switch(patterns[state].m_elems[e->leaf_val-1]->op_code->id_argfmt) {
case NOARG:
fprintf(stderr,"error: mnem %d has no argument\n",e->leaf_val);
1987-01-15 18:12:26 +00:00
nerrors++;
break;
case CST:
case CSTOPT:
fprintf(ofile,"CST(patt[%d])",e->leaf_val-1);
1987-01-15 18:12:26 +00:00
break;
case LAB:
fprintf(ofile,"LAB(patt[%d])",e->leaf_val-1);
1987-01-15 18:12:26 +00:00
break;
case DEFILB:
fprintf(ofile,"DEFILB(patt[%d])",e->leaf_val-1);
1987-01-15 18:12:26 +00:00
break;
case PNAM:
fprintf(ofile,"PNAM(patt[%d])",e->leaf_val-1);
1987-01-15 18:12:26 +00:00
break;
case EXT:
fprintf(ofile,"OO_offset(patt+%d)",e->leaf_val-1);
1987-01-15 18:12:26 +00:00
break;
}
break;
case PSIZE:
fprintf(ofile,"OO_PSIZE"); break;
1987-01-15 18:12:26 +00:00
case WSIZE:
fprintf(ofile,"OO_WSIZE"); break;
1987-01-15 18:12:26 +00:00
case INT:
fprintf(ofile,"%d",e->leaf_val); break;
1987-01-15 18:12:26 +00:00
}
}
PRIVATE
outext(e)
struct exp_node *e;
{
if(e->node_type!=PATARG) {
fprintf(stderr,"Internal error in outext of parser\n");
1987-01-15 18:12:26 +00:00
nerrors++;
}
fprintf(ofile,"patt+%d",e->leaf_val-1);
1987-01-15 18:12:26 +00:00
}
PRIVATE
outop(op)
1987-01-15 18:12:26 +00:00
int op;
{
switch(op) {
case LOGAND: fprintf(ofile,"&&"); break;
case LOGOR: fprintf(ofile,"||"); break;
case BITAND: fprintf(ofile,"&"); break;
case BITOR: fprintf(ofile,"|"); break;
case XOR: fprintf(ofile,"^"); break;
case MINUS: fprintf(ofile,"-"); break;
case PLUS: fprintf(ofile,"+"); break;
case TIMES: fprintf(ofile,"*"); break;
case DIV: fprintf(ofile,"/"); break;
case MOD: fprintf(ofile,"%%"); break;
case EQ: fprintf(ofile,"=="); break;
case NE: fprintf(ofile,"!="); break;
case LT: fprintf(ofile,"<"); break;
case LE: fprintf(ofile,"<="); break;
case GT: fprintf(ofile,">"); break;
case GE: fprintf(ofile,">="); break;
case LSHIFT: fprintf(ofile,"<<"); break;
case RSHIFT: fprintf(ofile,">>"); break;
case NOT: fprintf(ofile,"!"); break;
case COMP: fprintf(ofile,"~"); break;
case UPLUS: fprintf(ofile,"+"); break;
case UMINUS: fprintf(ofile,"-"); break;
case SAMESIGN: fprintf(ofile,"OO_signsame("); break;
case SFIT: fprintf(ofile,"OO_sfit("); break;
case UFIT: fprintf(ofile,"OO_ufit("); break;
case ROTATE: fprintf(ofile,"OO_rotate("); break;
case SAMEEXT: fprintf(ofile,"OO_extsame("); break;
case SAMENAM: fprintf(ofile,"OO_namsame("); break;
1987-01-15 18:12:26 +00:00
}
}