Converted dfa to use row displacement compaction
This commit is contained in:
parent
ead2873ab5
commit
545bed355d
|
@ -1,5 +1,5 @@
|
||||||
# $Header$
|
# $Header$
|
||||||
EMHOME = /proj/em/Work
|
EMHOME = ../../..
|
||||||
INSTALL = $(EMHOME)/modules/install
|
INSTALL = $(EMHOME)/modules/install
|
||||||
COMPARE = $(EMHOME)/modules/compare
|
COMPARE = $(EMHOME)/modules/compare
|
||||||
LINT = lint
|
LINT = lint
|
||||||
|
|
|
@ -6,8 +6,8 @@ static char rcsidp3[] = "$Header$";
|
||||||
|
|
||||||
#define UPDATEWORST(backups) if(backups>mostbackups) mostbackups = backups;
|
#define UPDATEWORST(backups) if(backups>mostbackups) mostbackups = backups;
|
||||||
|
|
||||||
findworst(repl)
|
findworst(patt,repl)
|
||||||
struct mnems repl;
|
struct mnems patt,repl;
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
/* Find the pattern that requires the most backup of output queue.
|
/* Find the pattern that requires the most backup of output queue.
|
||||||
|
@ -26,11 +26,12 @@ findworst(repl)
|
||||||
/* requires a backup of n-i+1 instructions and a goto to state 0.
|
/* requires a backup of n-i+1 instructions and a goto to state 0.
|
||||||
*/
|
*/
|
||||||
int n = repl.m_len;
|
int n = repl.m_len;
|
||||||
|
int diff = patt.m_len - repl.m_len;
|
||||||
int first,i;
|
int first,i;
|
||||||
int s;
|
int s;
|
||||||
int mostbackups = 0;
|
int mostbackups = 0;
|
||||||
if(n==0) {
|
if(n==0) {
|
||||||
fprintf(ofile,"\t\tOO_backup(%d);\n", maxpattern-1);
|
fprintf(ofile,"\t\tOO_mkrepl(0,%d,%d);\n",diff,maxpattern-1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for(s=1;s<=higheststate;s++) {
|
for(s=1;s<=higheststate;s++) {
|
||||||
|
@ -56,7 +57,7 @@ findworst(repl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fprintf(ofile,"\t\tOO_backup(%d);\n",mostbackups);
|
fprintf(ofile,"\t\tOO_mkrepl(%d,%d,%d);\n",n,diff,mostbackups);
|
||||||
}
|
}
|
||||||
|
|
||||||
findfail(state,resout,rescpy,resgto)
|
findfail(state,resout,rescpy,resgto)
|
||||||
|
|
|
@ -6,7 +6,7 @@ static char rcsidp2[] = "$Header$";
|
||||||
#include <em_flag.h>
|
#include <em_flag.h>
|
||||||
#include <em_spec.h>
|
#include <em_spec.h>
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
#define op_lab 255
|
#define op_lab sp_fpseu /* if you change this change nopt.h also */
|
||||||
|
|
||||||
#include <idf_pkg.body>
|
#include <idf_pkg.body>
|
||||||
|
|
||||||
|
|
|
@ -4,13 +4,18 @@ static char rcsid2[] = "$Header$";
|
||||||
|
|
||||||
#include "nopt.h"
|
#include "nopt.h"
|
||||||
|
|
||||||
extern int (*OO_fstate[])(); /* Initialized from patterns in dfa.c */
|
extern struct dfa OO_checknext[]; /* Initialized in dfa.c */
|
||||||
extern int OO_maxpattern; /* Initialized from patterns in dfa.c */
|
extern struct dfa *OO_base[]; /* Initialized in dfa.c */
|
||||||
extern int OO_maxreplacement; /* Initialized from patterns 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_mnem[][4];
|
||||||
extern char em_pseu[][4];
|
extern char em_pseu[][4];
|
||||||
|
|
||||||
|
int OO_state = 0;
|
||||||
|
|
||||||
p_instr OO_buffer;
|
p_instr OO_buffer;
|
||||||
p_instr OO_patternqueue;
|
p_instr OO_patternqueue;
|
||||||
p_instr OO_nxtpatt;
|
p_instr OO_nxtpatt;
|
||||||
|
@ -69,9 +74,23 @@ O_close()
|
||||||
OO_dfa(last)
|
OO_dfa(last)
|
||||||
register int last;
|
register int last;
|
||||||
{
|
{
|
||||||
|
register struct dfa *b;
|
||||||
|
register struct dodefault *d;
|
||||||
|
register int (*f)();
|
||||||
for(;;) {
|
for(;;) {
|
||||||
printstate("OO_dfa");
|
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;
|
if (!OO_endbackup) return;
|
||||||
last = (OO_nxtpatt++)->em_opcode;
|
last = (OO_nxtpatt++)->em_opcode;
|
||||||
if (OO_nxtpatt >= OO_endbackup)
|
if (OO_nxtpatt >= OO_endbackup)
|
||||||
|
@ -197,18 +216,17 @@ OO_mkext(p,opcode,arg,off)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OO_backup(n)
|
OO_mkrepl(lrepl,diff,numbkup)
|
||||||
int n;
|
int lrepl,diff,numbkup;
|
||||||
{
|
{
|
||||||
/* copy the replacement queue into the buffer queue */
|
/* copy the replacement queue into the buffer queue */
|
||||||
/* then move the pattern queue back n places */
|
/* then move the pattern queue back n places */
|
||||||
register p_instr p,q;
|
register p_instr p,q;
|
||||||
register int i,lrepl, diff;
|
register int i;
|
||||||
printstate("Before backup");
|
printstate("Before backup");
|
||||||
lrepl = OO_nxtrepl-OO_replqueue;
|
|
||||||
if(OO_endbackup) {
|
if(OO_endbackup) {
|
||||||
/* move the region between OO_nxtpatt and 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 */
|
/* move left by diff */
|
||||||
BTSCPY(p,q,i,OO_nxtpatt-diff,OO_nxtpatt,OO_endbackup-OO_nxtpatt);
|
BTSCPY(p,q,i,OO_nxtpatt-diff,OO_nxtpatt,OO_endbackup-OO_nxtpatt);
|
||||||
OO_nxtpatt -= diff;
|
OO_nxtpatt -= diff;
|
||||||
|
@ -233,28 +251,16 @@ OO_backup(n)
|
||||||
OO_nxtrepl = OO_replqueue;
|
OO_nxtrepl = OO_replqueue;
|
||||||
OO_patternqueue += lrepl;
|
OO_patternqueue += lrepl;
|
||||||
}
|
}
|
||||||
/* now move the position of interest back n instructions */
|
/* now move the position of interest back nunbkup instructions */
|
||||||
if ((OO_patternqueue-OO_buffer) < n)
|
if ((OO_patternqueue-OO_buffer) < numbkup)
|
||||||
n = (OO_patternqueue-OO_buffer);
|
numbkup = (OO_patternqueue-OO_buffer);
|
||||||
OO_nxtpatt = OO_patternqueue -= n;
|
OO_nxtpatt = OO_patternqueue -= numbkup;
|
||||||
if(!OO_endbackup && n)
|
if(!OO_endbackup && numbkup)
|
||||||
OO_endbackup = OO_patternqueue+n;
|
OO_endbackup = OO_patternqueue+numbkup;
|
||||||
OO_state = 0;
|
OO_state = 0;
|
||||||
printstate("After backup");
|
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
|
#ifdef DEBUG
|
||||||
dumpstate(mess)
|
dumpstate(mess)
|
||||||
char *mess;
|
char *mess;
|
||||||
|
|
|
@ -20,6 +20,16 @@
|
||||||
|
|
||||||
typedef struct e_instr *p_instr;
|
typedef struct e_instr *p_instr;
|
||||||
|
|
||||||
|
struct dfa {
|
||||||
|
short check;
|
||||||
|
short next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dodefault {
|
||||||
|
short numout;
|
||||||
|
short next;
|
||||||
|
};
|
||||||
|
|
||||||
extern p_instr OO_buffer;
|
extern p_instr OO_buffer;
|
||||||
extern p_instr OO_patternqueue;
|
extern p_instr OO_patternqueue;
|
||||||
extern p_instr OO_nxtpatt;
|
extern p_instr OO_nxtpatt;
|
||||||
|
|
|
@ -90,66 +90,136 @@ RENAME(x,y)
|
||||||
unlink(x);
|
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
|
PRIVATE
|
||||||
outdfa()
|
outdfa()
|
||||||
{
|
{
|
||||||
int s;
|
register int s,i;
|
||||||
struct state *p;
|
register struct state *p;
|
||||||
int nout, ncpy, ngto;
|
int nout, ncpy, ngto;
|
||||||
int seenswitch;
|
int row[MAXOPCODE];
|
||||||
|
int numinrow;
|
||||||
|
int numentries = 0;
|
||||||
|
|
||||||
fprintf(ofile,"#include \"nopt.h\"\n");
|
fprintf(ofile,"#include \"nopt.h\"\n");
|
||||||
fprintf(ofile,"\n");
|
fprintf(ofile,"\n");
|
||||||
fprintf(ofile,"int OO_maxreplacement = %d;\n", maxreplacement);
|
fprintf(ofile,"int OO_maxreplacement = %d;\n", maxreplacement);
|
||||||
fprintf(ofile,"int OO_state = 0;\n");
|
|
||||||
fprintf(ofile,"\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++) {
|
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;
|
||||||
}
|
}
|
||||||
fprintf(ofile,"\nint (*OO_fstate[])()=\n{\n");
|
|
||||||
for(s=0;s<=higheststate;s++) {
|
/* output the arrays */
|
||||||
fprintf(ofile,"\tdfa%d,\n",s);
|
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,"};\n\n");
|
fprintf(ofile,"};\n\n");
|
||||||
|
fprintf(ofile,"struct dfa *OO_base[] = {\n");
|
||||||
for(s=0;s<=higheststate;s++) {
|
for(s=0;s<=higheststate;s++) {
|
||||||
fprintf(ofile,"static dfa%d(opcode)\n",s);
|
fprintf(ofile,"\t/* %4d: ",s);
|
||||||
fprintf(ofile,"\tint opcode;\n");
|
|
||||||
fprintf(ofile,"{\n");
|
|
||||||
fprintf(ofile,"\t/* ");
|
|
||||||
outmnems(patterns[s]);
|
outmnems(patterns[s]);
|
||||||
fprintf(ofile," */\n");
|
fprintf(ofile,"*/\t");
|
||||||
seenswitch = 0;
|
if(base[s]==EMPTY)
|
||||||
for(p=states[s];p!=(struct state *)NULL;p=p->next) {
|
fprintf(ofile,"0,\n");
|
||||||
if(!seenswitch) {
|
else
|
||||||
seenswitch++;
|
fprintf(ofile,"&OO_checknext[%4d],\n", base[s]);
|
||||||
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,"};\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);
|
||||||
|
}
|
||||||
|
fprintf(ofile,"};\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
PRIVATE
|
PRIVATE
|
||||||
|
@ -168,9 +238,24 @@ outdotrans()
|
||||||
struct action *a;
|
struct action *a;
|
||||||
int seennontested;
|
int seennontested;
|
||||||
fprintf(ofile,"#include \"nopt.h\"\n\n");
|
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++) {
|
for(s=0;s<=higheststate;s++) {
|
||||||
if(actions[s]!=(struct action *)NULL) {
|
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,"\tregister p_instr patt = OO_patternqueue;\n");
|
||||||
fprintf(ofile,"\t/* ");
|
fprintf(ofile,"\t/* ");
|
||||||
outmnems(patterns[s]);
|
outmnems(patterns[s]);
|
||||||
|
@ -194,13 +279,8 @@ outdotrans()
|
||||||
outoneaction(s,a);
|
outoneaction(s,a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!seennontested)
|
|
||||||
fprintf(ofile,"\tOO_state=%d;\n",s);
|
|
||||||
fprintf(ofile,"}\n");
|
fprintf(ofile,"}\n");
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
* else fprintf(ofile,"\nOO_%ddotrans() {\n\tOO_state=%d;\n}\n",s,s);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,7 +296,7 @@ outoneaction(s,a)
|
||||||
fprintf(ofile,"\t\tif(OO_wrstats) fprintf(stderr,\"%d\\n\");\n",a->linenum);
|
fprintf(ofile,"\t\tif(OO_wrstats) fprintf(stderr,\"%d\\n\");\n",a->linenum);
|
||||||
fprintf(ofile,"#endif\n");
|
fprintf(ofile,"#endif\n");
|
||||||
outrepl(s,a->replacement);
|
outrepl(s,a->replacement);
|
||||||
findworst(a->replacement);
|
findworst(patterns[s],a->replacement);
|
||||||
}
|
}
|
||||||
|
|
||||||
PRIVATE
|
PRIVATE
|
||||||
|
|
Loading…
Reference in a new issue