#include "nopt.h"
-extern int (*OO_fstate[])(); /* Initialized from patterns in dfa.c */
-extern int OO_maxpattern; /* Initialized from patterns in dfa.c */
-extern int OO_maxreplacement; /* Initialized from patterns in dfa.c */
+extern struct dfa OO_checknext[]; /* Initialized in dfa.c */
+extern struct dfa *OO_base[]; /* Initialized in dfa.c */
+extern struct dodefault OO_default[]; /* Initialized in dfa.c */
+extern int OO_maxpattern; /* Initialized in dfa.c */
+extern int OO_maxreplacement; /* Initialized in dfa.c */
+extern int (*OO_ftrans[])(); /* Initialized in trans.c */
extern char em_mnem[][4];
extern char em_pseu[][4];
+int OO_state = 0;
+
p_instr OO_buffer;
p_instr OO_patternqueue;
p_instr OO_nxtpatt;
OO_dfa(last)
register int last;
{
+ register struct dfa *b;
+ register struct dodefault *d;
+ register int (*f)();
for(;;) {
printstate("OO_dfa");
- (*OO_fstate[OO_state])(last);
+ if((b=OO_base[OO_state]) && ((b += last)->check==OO_state)) {
+ if(f=OO_ftrans[OO_state = b->next]) f();
+ }
+ else if (OO_state) {
+ /* consult default entry */
+ d = &OO_default[OO_state];
+ if(!OO_endbackup) OO_endbackup = OO_nxtpatt;
+ OO_nxtpatt--;
+ OO_patternqueue += d->numout;
+ if(f=OO_ftrans[OO_state = d->next]) f();
+ }
+ else OO_flush();
if (!OO_endbackup) return;
last = (OO_nxtpatt++)->em_opcode;
if (OO_nxtpatt >= OO_endbackup)
}
}
-OO_backup(n)
- int n;
+OO_mkrepl(lrepl,diff,numbkup)
+ int lrepl,diff,numbkup;
{
/* copy the replacement queue into the buffer queue */
/* then move the pattern queue back n places */
register p_instr p,q;
- register int i,lrepl, diff;
+ register int i;
printstate("Before backup");
- lrepl = OO_nxtrepl-OO_replqueue;
if(OO_endbackup) {
/* move the region between OO_nxtpatt and OO_endbackup */
- if ((diff = (OO_nxtpatt-OO_patternqueue) - lrepl) > 0) {
+ if (diff > 0) {
/* move left by diff */
BTSCPY(p,q,i,OO_nxtpatt-diff,OO_nxtpatt,OO_endbackup-OO_nxtpatt);
OO_nxtpatt -= diff;
OO_nxtrepl = OO_replqueue;
OO_patternqueue += lrepl;
}
- /* now move the position of interest back n instructions */
- if ((OO_patternqueue-OO_buffer) < n)
- n = (OO_patternqueue-OO_buffer);
- OO_nxtpatt = OO_patternqueue -= n;
- if(!OO_endbackup && n)
- OO_endbackup = OO_patternqueue+n;
+ /* now move the position of interest back nunbkup instructions */
+ if ((OO_patternqueue-OO_buffer) < numbkup)
+ numbkup = (OO_patternqueue-OO_buffer);
+ OO_nxtpatt = OO_patternqueue -= numbkup;
+ if(!OO_endbackup && numbkup)
+ OO_endbackup = OO_patternqueue+numbkup;
OO_state = 0;
printstate("After backup");
}
-OO_dodefault(numout, newstate)
- int numout;
- int newstate;
-{
- printstate("Before dodefault");
- if(!OO_endbackup) OO_endbackup = OO_nxtpatt;
- OO_nxtpatt--;
- OO_patternqueue += numout;
- OO_state = newstate;
- printstate("After dodefault");
-}
-
#ifdef DEBUG
dumpstate(mess)
char *mess;
unlink(x);
}
+# 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("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;
+ }
+}
+
PRIVATE
outdfa()
{
- int s;
- struct state *p;
+ register int s,i;
+ register struct state *p;
int nout, ncpy, ngto;
- int seenswitch;
+ 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,"int OO_state = 0;\n");
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++) {
- fprintf(ofile,"static dfa%d();\n",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;
+ }
+
+ /* output the arrays */
+ printf("Compacted %d entries into %d positions\n",numentries,maxpos);
+ 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,"\nint (*OO_fstate[])()=\n{\n");
+ fprintf(ofile,"};\n\n");
+ fprintf(ofile,"struct dfa *OO_base[] = {\n");
for(s=0;s<=higheststate;s++) {
- fprintf(ofile,"\tdfa%d,\n",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,"static dfa%d(opcode)\n",s);
- fprintf(ofile,"\tint opcode;\n");
- fprintf(ofile,"{\n");
- fprintf(ofile,"\t/* ");
+ fprintf(ofile,"\t/* %4d: ",s);
outmnems(patterns[s]);
- fprintf(ofile," */\n");
- seenswitch = 0;
- for(p=states[s];p!=(struct state *)NULL;p=p->next) {
- if(!seenswitch) {
- seenswitch++;
- fprintf(ofile,"\tswitch(opcode) {\n");
- }
- fprintf(ofile,"\tcase op_%s: ",p->op->id_text);
- if(actions[p->goto_state]==(struct action *)NULL)
- fprintf(ofile,"OO_state = %d; ",p->goto_state);
- else fprintf(ofile,"OO_%ddotrans(); ",p->goto_state);
- fprintf(ofile,"break;\n");
- }
- if(s==0) {
- if(!seenswitch) {
- seenswitch++;
- fprintf(ofile,"\tswitch(opcode) {\n");
- }
- fprintf(ofile,"\tdefault:\n");
- fprintf(ofile,"\t\tOO_flush();\n");
- fprintf(ofile,"\t\tbreak;\n");
- }
- else {
- if(seenswitch) fprintf(ofile,"\tdefault:\n");
- findfail(s,&nout,&ncpy,&ngto);
- fprintf(ofile,"\t\tOO_dodefault(%d,%d);\n",nout,ngto);
- if(actions[ngto]!=NULL)
- fprintf(ofile,"\t\tOO_%ddotrans();\n",ngto);
- if(seenswitch) fprintf(ofile,"\t\tbreak;\n");
- }
- if(seenswitch) fprintf(ofile,"\t}\n");
- fprintf(ofile,"}\n");
- fprintf(ofile,"\n");
+ fprintf(ofile,"*/\t");
+ findfail(s,&nout,&ncpy,&ngto);
+ fprintf(ofile,"{%4d,%4d},\n", nout,ngto);
}
+ fprintf(ofile,"};\n\n");
}
PRIVATE
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++) {
if(actions[s]!=(struct action *)NULL) {
- fprintf(ofile,"\nOO_%ddotrans() {\n",s);
+ fprintf(ofile,"\nstatic do%dtrans() {\n",s);
fprintf(ofile,"\tregister p_instr patt = OO_patternqueue;\n");
fprintf(ofile,"\t/* ");
outmnems(patterns[s]);
outoneaction(s,a);
}
}
- if(!seennontested)
- fprintf(ofile,"\tOO_state=%d;\n",s);
fprintf(ofile,"}\n");
}
- /*
- * else fprintf(ofile,"\nOO_%ddotrans() {\n\tOO_state=%d;\n}\n",s,s);
- */
}
}
fprintf(ofile,"\t\tif(OO_wrstats) fprintf(stderr,\"%d\\n\");\n",a->linenum);
fprintf(ofile,"#endif\n");
outrepl(s,a->replacement);
- findworst(a->replacement);
+ findworst(patterns[s],a->replacement);
}
PRIVATE