Makefile
bootgram.y
bootlex.l
+main.c
+booth.h
# LEXLIB is system dependent, try -ll or -lln first
LEXLIB=-lln
-cgg: bootgram.o
- $(CC) $(LDFLAGS) bootgram.o $(LIBS) $(LEXLIB) -o cgg
+cgg: bootgram.o main.o bootlex.o
+ $(CC) $(LDFLAGS) bootgram.o main.o bootlex.o $(LIBS) $(LEXLIB) -o cgg
bootgram.c: bootgram.y
@echo expect 1 shift/reduce conflict
- yacc bootgram.y
+ yacc -d bootgram.y
mv y.tab.c bootgram.c
install: cgg
cmp: cgg
cmp cgg ../../lib/cgg
-lint: bootgram.c
- lint $(LINTOPTS) bootgram.c
+lint: bootgram.c main.c bootlex.c
+ lint $(LINTOPTS) bootgram.c main.c bootlex.c
clean:
- rm -f bootgram.o bootgram.c bootlex.c cgg
-bootgram.o: bootlex.c
+ rm -f *.o bootgram.c bootlex.c cgg y.tab.h
+bootgram.o: booth.h
bootgram.o: ../../h/cg_pattern.h
+bootlex.o: booth.h
+bootlex.o: ../../h/cg_pattern.h
+main.o: booth.h
+main.o: ../../h/cg_pattern.h
* Author: Hans van Staveren
*/
-#include <local.h>
-
-#if BIGMACHINE
-#define BORS(x,y) x
-#else
-#define BORS(x,y) y
-#endif
-/* Tunable constants */
-
-#define MAXALLREG 5 /* Maximum number of allocates per rule */
-#define MAXREGS BORS(36,32) /* Total number of registers */
-#define MAXREGVARS 8 /* Maximum regvars per type */
-#define MAXPROPS 16 /* Total number of register properties */
-#define MAXTOKENS BORS(75,32) /* Different kind of tokens */
-#define MAXSETS BORS(100,80) /* Number of tokenexpressions definable */
-#define MAXEMPATLEN 25 /* Maximum length of EM-pattern/replacement */
-#define TOKENSIZE 5 /* Maximum number of fields in token struct */
-#define MAXINSTANCE BORS(250,120) /* Maximum number of different tokeninstances */
-#define MAXSTRINGS BORS(800,400)/* Maximum number of different codestrings */
-#define MAXPATTERN BORS(8000,6000) /* Maximum number of bytes in pattern[] */
-#define MAXNODES BORS(500,400) /* Maximum number of expression nodes */
-#define MAXMEMBERS 2 /* Maximum number of subregisters per reg */
-#define NMOVES BORS(50,30) /* Maximum number of move definitions */
-#define MAXC1 20 /* Maximum of coercions type 1 */
-#define MAXC2 20 /* Maximum of coercions type 2 */
-#define MAXC3 20 /* Maximum of coercions type 3 */
-#define MAXSPLIT 4 /* Maximum degree of split */
-#define MAXNSTR 40 /* Maximum consecutive strings in coderule */
-
-char *hname="tables.h";
-char *cname="tables.c";
-char *iname=0; /* stdin */
-
-/* Derived constants */
-
-#define SETSIZE ((MAXREGS+1+MAXTOKENS+15)>>4)
-#define PROPSETSIZE ((MAXPROPS+15)>>4)
-
-#define BMASK 0377
-#define BSHIFT 8
-
-#define TRUE 1
-#define FALSE 0
-
-#define MAXPATLEN 7 /* Maximum length of tokenpatterns */
-
-typedef char byte;
-typedef char * string;
-
-char *malloc(),*myalloc();
-
-#include <stdio.h>
-#include <assert.h>
-#include <ctype.h>
-#include <em_spec.h>
-#include <em_flag.h>
-#include <em_reg.h>
-#include <cg_pattern.h>
-
-typedef struct list1str {
- struct list1str *l1next;
- string l1name;
-} *list1;
-typedef struct list2str {
- struct list2str *l2next;
- list1 l2list;
-} *list2;
-typedef struct list3str {
- struct list3str *l3next;
- list2 l3list;
-} *list3;
-
-typedef struct reginfo {
- string rname;
- string rrepr;
- int rsize;
- int rmembers[MAXMEMBERS];
- int rregvar;
- short rprop[PROPSETSIZE];
-} *reginfo;
-
-typedef struct tokeninfo {
- string t_name;
- list2 t_struct;
- struct {
- int t_type;
- string t_sname;
- } t_fields[TOKENSIZE-1];
- int t_size;
- cost_t t_cost;
- int t_format;
-} token_t,*token_p;
-
-typedef struct ident {
- struct ident *i_next;
- string i_name;
- int i_type;
-# define IREG 1
-# define IPRP 2
-# define ITOK 3
-# define IEXP 4
- union {
- int i_regno;
- int i_prpno;
- int i_tokno;
- int i_expno;
- } i_i;
-} ident_t,*ident_p;
-
-#define ITABSIZE 32
-ident_p identtab[ITABSIZE];
-
-#define LOOKUP 0
-#define HALFWAY 1
-#define ENTER 2
-#define JUSTLOOKING 3
-
-
-typedef struct expr {
- int expr_typ;
-# define TYPINT 1
-# define TYPREG 2
-# define TYPSTR 3
-# define TYPBOOL 4
- int expr_index;
-} expr_t,*expr_p;
-
-unsigned cc1=1,cc2=1,cc3=1,cc4=1;
-
-node_t nodes[MAXNODES];
-node_p lastnode=nodes+1;
-
-string codestrings[MAXSTRINGS];
-int ncodestrings;
-
-int strar[MAXNSTR];
-int nstr;
-
-int pathash[256];
-
-reginfo machregs[MAXREGS];
-char stregclass[MAXREGS];
-int nmachregs=1;
-int nregclasses=1;
-int maxmembers;
-struct {
- ident_p propname;
- set_t propset;
-} machprops[MAXPROPS];
-int nprops=0;
-token_t machtokens[MAXTOKENS];
-int nmachtokens=1;
-set_t machsets[MAXSETS];
-int nmachsets=0;
-int patmnem[MAXEMPATLEN];
-int empatlen;
-int maxempatlen;
-int empatexpr;
-int maxrule=1;
-int pattokexp[MAXPATLEN];
-int tokpatlen;
-int lookident=0; /* lexical analyzer flag */
-list3 structpool=0;
-int nallreg;
-int allreg[MAXALLREG];
-int maxallreg;
-int lino=0;
-int nerrors=0;
-int curtokexp;
-expr_t arexp[TOKENSIZE];
-int narexp;
-inst_t arinstance[MAXINSTANCE];
-int narinstance=1;
-move_t machmoves[NMOVES];
-int nmoves=0;
-byte pattern[MAXPATTERN];
-int npatbytes=0;
-int prevind;
-int rulecount; /* Temporary index for ... construct */
-int ncoderules=0;
-int codebytes=0;
-FILE *cfile;
-FILE *hfile;
-int maxtokensize=0;
-int dealflag;
-int emrepllen;
-int replmnem[MAXEMPATLEN];
-int tokrepllen;
-int replinst[MAXPATLEN];
-int replexpr[MAXPATLEN];
-c1_t c1coercs[MAXC1];
-c2_t c2coercs[MAXC2];
-c3_t c3coercs[MAXC3];
-int nc1=0,nc2=0,nc3=0;
-int maxsplit=0;
-int wsize= -1;
-int psize= -1;
-int bsize= -1;
-char *fmt=0;
-
-int cchandled;
-int ccspoiled;
-int ccregexpr;
-int ccinstanceno;
-int cocopropno;
-int cocosetno;
-int allexpno;
-
-int rvused; /* regvars used */
-int nregvar[4]; /* # of register variables of all kinds */
-int rvnumbers[4][MAXREGVARS]; /* The register numbers */
-
-#define chktabsiz(size,maxsize,which) if(size>=maxsize) tabovf(which)
-
-#define MUST1BEINT(e) int exp1=e.expr_index;tstint(e)
-#define MUST2BEINT(e1,e2) int exp1=e1.expr_index,exp2=e2.expr_index;tstint(e1);tstint(e2)
-#define MUST1BEBOOL(e) int exp1=e.expr_index;tstbool(e)
-#define MUST2BEBOOL(e1,e2) int exp1=e1.expr_index,exp2=e2.expr_index;tstbool(e1);tstbool(e2)
+#define extern
+#include "booth.h"
%}
;
%%
-
-char * myalloc(n) {
- register char *p;
-
- p= (char*) malloc(n);
- if (p==0) {
- yyerror("Out of core");
- exit(1);
- }
- return(p);
-}
-
-tstint(e) expr_t e; {
-
- if(e.expr_typ != TYPINT)
- yyerror("Must be integer expression");
-}
-
-tstbool(e) expr_t e; {
-
- if(e.expr_typ != TYPBOOL)
- yyerror("Must be boolean expression");
-}
-
-structsize(s) register list2 s; {
- register list1 l;
- register sum;
-
- sum = 0;
- while ( s != 0 ) {
- l = s->l2list->l1next;
- while ( l != 0 ) {
- sum++;
- l = l->l1next;
- }
- s = s->l2next;
- }
- return(sum);
-}
-
-list2 lookstruct(ll) list2 ll; {
- list3 l3;
- 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)
- ;
- if (l11!=0 || l12!=0)
- goto contin;
- }
- if(l21==0 && l22==0)
- return(l3->l3list);
- contin:;
- }
- l3 = (list3) myalloc(sizeof(struct list3str));
- l3->l3next=structpool;
- l3->l3list=ll;
- structpool=l3;
- return(ll);
-}
-
-instno(inst) inst_t inst; {
- register i,j;
-
- for(i=1;i<narinstance;i++) {
- if (arinstance[i].in_which != inst.in_which)
- continue;
- for(j=0;j<TOKENSIZE;j++)
- if(arinstance[i].in_info[j] != inst.in_info[j])
- goto cont;
- return(i);
- cont:;
- }
- chktabsiz(narinstance,MAXINSTANCE,"Instance table");
- arinstance[narinstance] = inst;
- return(narinstance++);
-}
-
-string scopy(s) string s; {
- register string t;
-
- t = (char *) myalloc(strlen(s)+1);
- strcpy(t,s);
- return(t);
-}
-
-strlookup(s) string s; {
- register i;
-
- for(i=0;i<ncodestrings;i++)
- if(strcmp(s,codestrings[i])==0)
- return(i);
- chktabsiz(ncodestrings,MAXSTRINGS,"string table");
- codestrings[ncodestrings] = scopy(s);
- return(ncodestrings++);
-}
-
-stringno(s) register string s; {
- char buf[256];
- register char *p=buf;
-
- while(*s != 0) switch(*s) {
- default:
- *p++ = *s++;
- continue;
- case '$':
- s++;
- 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++;
- 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;
- }
- }
- } 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;
- return(strlookup(buf));
-}
-
-tabovf(tablename) string tablename; {
- char buf[256];
-
- sprintf(buf,"%s overflow",tablename);
- yyerror(buf);
- exit(-1);
-}
-
-main(argc,argv) char *argv[]; {
-
- while (--argc) {
- ++argv;
- 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;
- }
- } else {
- iname= argv[0];
- }
- }
- inithash();
- initio();
- inittables();
- yyparse();
- if (nerrors==0) {
- compueq();
- hashpatterns();
- finishio();
- verbose();
- }
- debug();
- exit(nerrors);
-}
-
-lookup(comm,operator,lnode,rnode) {
- register node_p p;
-
- for (p=nodes+1;p<lastnode;p++) {
- if (p->ex_operator != operator)
- continue;
- if (!(p->ex_lnode == lnode && p->ex_rnode == rnode ||
- comm && p->ex_lnode == rnode && p->ex_rnode == lnode))
- continue;
- return(p-nodes);
- }
- if (lastnode >= &nodes[MAXNODES])
- yyerror("node table overflow");
- lastnode++;
- p->ex_operator = operator;
- p->ex_lnode = lnode;
- p->ex_rnode = rnode;
- return(p-nodes);
-}
-
-compueq() {
- register i,j;
-
- for (i=1;i<nmachregs;i++) {
- for (j=1;j<i;j++)
- if (eqregclass(i,j)) {
- stregclass[i] = stregclass[j];
- break;
- }
- if (j==i)
- stregclass[i] = nregclasses++;
- }
-}
-
-eqregclass(r1,r2) {
- register reginfo rp1,rp2;
- register i;
- short regbits[(MAXREGS+15)>>4];
- int member;
-
- rp1 = machregs[r1]; rp2 = machregs[r2];
- for (i=0;i<((nprops+15)>>4);i++)
- if (rp1->rprop[i] != rp2->rprop[i])
- return(0);
- for (i=0;i<((MAXREGS+15)>>4);i++)
- regbits[i] = 0;
- for (i=0;i<maxmembers;i++) {
- if (member = rp1->rmembers[i])
- regbits[member>>4] |= (1<<(member&017));
- }
- for (i=0;i<maxmembers;i++) {
- member = rp2->rmembers[i];
- if (regbits[member>>4]&(1<<(member&017)))
- return(0);
- }
- return(1);
-}
-
-unsigned hash(name) register string name; {
- register unsigned sum;
- register i;
-
- for (sum=i=0;*name;i+=3)
- sum ^= (*name++)<<(i&07);
- return(sum);
-}
-
-ident_p ilookup(name,enterf) string name; int enterf; {
- register ident_p p,*pp;
-
- pp = &identtab[hash(name)%ITABSIZE];
- while (*pp != 0) {
- if (strcmp((*pp)->i_name,name)==0)
- if (enterf != ENTER)
- return(*pp);
- else
- yyerror("Multiply defined symbol");
- pp = &(*pp)->i_next;
- }
- if (enterf == LOOKUP)
- yyerror("Undefined symbol");
- if (enterf == JUSTLOOKING)
- return(0);
- p = *pp = (ident_p) myalloc(sizeof(ident_t));
- p->i_name = name;
- p->i_next = 0;
- p->i_type = 0;
- return(p);
-}
-
-initio() {
-
- if (iname!=0 && freopen(iname,"r",stdin)==NULL) {
- fprintf(stderr,"Can't open %s\n",iname);
- exit(-1);
- }
- if ((cfile=fopen(cname,"w"))==NULL) {
- fprintf(stderr,"Can't create %s\n",cname);
- exit(-1);
- }
- if ((hfile=fopen(hname,"w"))==NULL) {
- fprintf(stderr,"Can't create %s\n",hname);
- exit(-1);
- }
- 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);
-}
-
-exprlookup(sett) set_t sett; {
- register i,j,ok;
-
- 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;
- ok=0;
- break;
- }
- if (ok)
- return(i);
- }
- chktabsiz(nmachsets,MAXSETS,"Expression table");
- machsets[nmachsets] = sett;
- return(nmachsets++);
-}
-
-inittables() {
- register reginfo r;
- register i;
- inst_t inst;
- set_t sett;
-
- 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;
- r->rregvar= -1;
- for(i=0;i<MAXMEMBERS;i++)
- r->rmembers[i] = 0;
- for(i=0;i<PROPSETSIZE;i++)
- r->rprop[i] = 0;
- r->rprop[cocopropno>>4] |= (1<<(cocopropno&017));
- chktabsiz(nmachregs,MAXREGS,"Register table");
- machregs[nmachregs++] = r;
- inst.in_which = IN_RIDENT;
- 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);
-}
-
-outregs() {
- register 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.
- */
- 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);
- 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);
- fprintf(cfile,"},{");
- for (j=0;j<((nmachregs+15)>>4);j++)
- fprintf(cfile,"%d,",rset[j]);
- fprintf(cfile,"}");
- }
- if (machregs[i]->rregvar>=0)
- fprintf(cfile,",1");
- fprintf(cfile,"},\n");
- }
- fprintf(cfile,"};\n\n");
-}
-
-finishio() {
- register i;
- register node_p np;
- int j;
- int setsize;
- register move_p mp;
-
- fprintf(cfile,"};\n\n");
- if (wsize>0)
- fprintf(hfile,"#define TEM_WSIZE %d\n",wsize);
- else
- yyerror("Wordsize undefined");
- if (psize>0)
- fprintf(hfile,"#define TEM_PSIZE %d\n",psize);
- else
- yyerror("Pointersize undefined");
- if (bsize>=0)
- fprintf(hfile,"#define TEM_BSIZE %d\n",bsize);
- else
- yyerror("EM_BSIZE undefined");
- 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();
- 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);
- fprintf(cfile,"};\n\nstring codestrings[] = {\n");
- for(i=0;i<ncodestrings;i++) {
- register char *p;
- p=codestrings[i];
- fprintf(cfile,"\t\"");
- while (*p) {
- register int c = (*p) & BMASK;
- if (! isascii(c) || iscntrl(c)) {
- fprintf(cfile,"\\%c%c%c",((c>>6) &03)+'0',
- ((c>>3)&07)+'0',(c&07)+'0');
- }
- else putc(c, cfile);
- p++;
- }
- 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]);
- 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];
- 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)
- 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);
- }
- fprintf(cfile,"\t0\n};\n");
- }
- fprintf(cfile,"struct reginfo **reglist[] = {\n");
- for (i=0;i<nprops;i++) {
- fprintf(cfile,"\trlist%d,\n",i);
- }
- 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();
-}
-
-outregvar() {
- register 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
- 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
- fprintf(cfile,"\t0,\n");
- fprintf(cfile,"};\n");
-}
-
-verbose() {
-
- 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);
-}
-
-inbetween() {
- register ident_p ip;
- register i,j;
- register move_p mp;
-
- lookident=1; /* for lexical analysis */
-
- chktabsiz(nmachsets+1,MAXSETS,"Expressiontable");
- for (i=0;i<SETSIZE;i++)
- machsets[nmachsets].set_val[i] = 0xFFFF;
- machsets[nmachsets].set_val[0] &= ~1;
- machsets[nmachsets].set_size = 0;
- ip=ilookup("SCRATCH",ENTER);
- ip->i_type=IEXP;
- ip->i_i.i_expno = nmachsets++;
-
- for (i=0;i<SETSIZE;i++)
- machsets[nmachsets].set_val[i] = 0xFFFF;
- machsets[nmachsets].set_size = 0;
- 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;
- 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
- */
-
- for (i=0;i<nprops;i++) {
- short *sp = machprops[i].propset.set_val;
-
- sp[0] |= 1;
- for (j=2;j<=nmachregs;j++)
- if (machregs[j-1]->rprop[i>>4]&(1<<(i&017)))
- sp[j>>4] |= (1<<(j&017));
- }
-}
-
-formconversion(p,tp) register char *p; register token_p tp; {
- char buf[256];
- register char *q=buf;
- char field[256];
- register char *f;
- int i;
-
- 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;
- return(strlookup(buf));
-}
-
-setfields(tp,format) register token_p tp; string format; {
- register i;
- list2 ll;
- register list1 l;
- int type;
-
- for(i=0;i<TOKENSIZE-1;i++)
- tp->t_fields[i].t_type = 0;
- i=0;
- for(ll=tp->t_struct;ll!=0;ll=ll->l2next) {
- l=ll->l2list;
- if(strcmp(l->l1name,"REGISTER")==0)
- type = TYPREG;
- else if (strcmp(l->l1name,"INT")==0)
- type = TYPINT;
- 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)
- tp->t_format = formconversion(format,tp);
- else
- tp->t_format = -1;
-}
-
-chkregexp(number) {
- register i;
-
- 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");
-}
-
-findstructel(number,name,t) string name; int *t; {
- register i;
- register token_p tp;
- register list2 structdecl;
- int offset;
-
- 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;
- 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");
- }
- }
- if (structdecl == 0) {
- yyerror("No structs in this set");
- return(0);
- }
- 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;
- return(offset+1);
- }
- yyerror("No such field in this struct");
- return(0);
-}
-
-extern char em_flag[];
-
-argtyp(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);
- }
-}
-
-commontype(e1,e2) expr_t e1,e2; {
-
- if(e1.expr_typ != e2.expr_typ)
- yyerror("Type incompatibility");
- return(e1.expr_typ);
-}
-
-extern char em_mnem[][4];
-
-#define HASHSIZE (2*(sp_lmnem-sp_fmnem))
-
-struct hashmnem {
- char h_name[3];
- byte h_value;
-} hashmnem[HASHSIZE];
-
-inithash() {
- register i;
-
- for(i=0;i<=sp_lmnem-sp_fmnem;i++)
- enter(em_mnem[i],i+sp_fmnem);
-}
-
-enter(name,value) char *name; {
- register unsigned h;
-
- h=hash(name)%HASHSIZE;
- while (hashmnem[h].h_name[0] != 0)
- h = (h+1)%HASHSIZE;
- strncpy(hashmnem[h].h_name,name,3);
- hashmnem[h].h_value = value;
-}
-
-int mlookup(name) char *name; {
- register unsigned h;
-
- 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 */
-}
-
-hashpatterns() {
- short index;
- register byte *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;
- }
-}
-
-debug() {
- register i,j;
-
- for(i=0;i<ITABSIZE;i++) {
- register ident_p ip;
- 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);
- }
-
- for(i=2;i<nmachregs;i++) {
- register reginfo rp;
-
- 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(")");
- for(j=0;j<nprops;j++)
- if(rp->rprop[j>>4]&(1<<(j&017)))
- printf(", %s",machprops[j].propname->i_name);
- printf(".\n");
- }
-}
-
-out(n) {
-
- assert(n>=0);
- if (n<128)
- outbyte(n);
- else {
- outbyte(n/256+128);
- outbyte(n%256);
- }
-}
-
-outbyte(n) {
-
- fprintf(cfile,"%d, ",n&BMASK);
- codebytes++;
-}
-
-pat(n) {
-
- assert(n>=0);
- if (n<128)
- patbyte(n);
- else {
- patbyte(n/256+128);
- patbyte(n%256);
- }
-}
-
-patshort(n) {
-
- patbyte(n&BMASK);
- patbyte(n>>BSHIFT);
-}
-
-patbyte(n) {
-
- chktabsiz(npatbytes,MAXPATTERN,"Pattern table");
- pattern[npatbytes++] = n;
-}
-
-max(a,b) {
-
- if (a>b)
- return(a);
- return(b);
-}
-
-#include "bootlex.c"
--- /dev/null
+#include <local.h>
+
+#ifdef extern
+#define INIT(x) = x
+#else
+#define INIT(x) /* empty */
+#endif
+
+#if BIGMACHINE
+#define BORS(x,y) x
+#else
+#define BORS(x,y) y
+#endif
+/* Tunable constants */
+
+#define MAXALLREG 5 /* Maximum number of allocates per rule */
+#define MAXREGS BORS(36,32) /* Total number of registers */
+#define MAXREGVARS 8 /* Maximum regvars per type */
+#define MAXPROPS 16 /* Total number of register properties */
+#define MAXTOKENS BORS(75,32) /* Different kind of tokens */
+#define MAXSETS BORS(100,80) /* Number of tokenexpressions definable */
+#define MAXEMPATLEN 25 /* Maximum length of EM-pattern/replacement */
+#define TOKENSIZE 5 /* Maximum number of fields in token struct */
+#define MAXINSTANCE BORS(250,120) /* Maximum number of different tokeninstances */
+#define MAXSTRINGS BORS(800,400)/* Maximum number of different codestrings */
+#define MAXPATTERN BORS(8000,6000) /* Maximum number of bytes in pattern[] */
+#define MAXNODES BORS(500,400) /* Maximum number of expression nodes */
+#define MAXMEMBERS 2 /* Maximum number of subregisters per reg */
+#define NMOVES BORS(50,30) /* Maximum number of move definitions */
+#define MAXC1 20 /* Maximum of coercions type 1 */
+#define MAXC2 20 /* Maximum of coercions type 2 */
+#define MAXC3 20 /* Maximum of coercions type 3 */
+#define MAXSPLIT 4 /* Maximum degree of split */
+#define MAXNSTR 40 /* Maximum consecutive strings in coderule */
+
+extern char *hname INIT("tables.h");
+extern char *cname INIT("tables.c");
+extern char *iname; /* stdin */
+
+/* Derived constants */
+
+#define SETSIZE ((MAXREGS+1+MAXTOKENS+15)>>4)
+#define PROPSETSIZE ((MAXPROPS+15)>>4)
+
+#define BMASK 0377
+#define BSHIFT 8
+
+#define TRUE 1
+#define FALSE 0
+
+#define MAXPATLEN 7 /* Maximum length of tokenpatterns */
+
+typedef char byte;
+typedef char * string;
+
+extern char *malloc(),*myalloc();
+
+#include <stdio.h>
+#include <assert.h>
+#include <ctype.h>
+#include <em_spec.h>
+#include <em_flag.h>
+#include <em_reg.h>
+#include <cg_pattern.h>
+
+typedef struct list1str {
+ struct list1str *l1next;
+ string l1name;
+} *list1;
+typedef struct list2str {
+ struct list2str *l2next;
+ list1 l2list;
+} *list2;
+typedef struct list3str {
+ struct list3str *l3next;
+ list2 l3list;
+} *list3;
+
+typedef struct reginfo {
+ string rname;
+ string rrepr;
+ int rsize;
+ int rmembers[MAXMEMBERS];
+ int rregvar;
+ short rprop[PROPSETSIZE];
+} *reginfo;
+
+typedef struct tokeninfo {
+ string t_name;
+ list2 t_struct;
+ struct {
+ int t_type;
+ string t_sname;
+ } t_fields[TOKENSIZE-1];
+ int t_size;
+ cost_t t_cost;
+ int t_format;
+} token_t,*token_p;
+
+typedef struct ident {
+ struct ident *i_next;
+ string i_name;
+ int i_type;
+# define IREG 1
+# define IPRP 2
+# define ITOK 3
+# define IEXP 4
+ union {
+ int i_regno;
+ int i_prpno;
+ int i_tokno;
+ int i_expno;
+ } i_i;
+} ident_t,*ident_p;
+
+#define ITABSIZE 32
+extern ident_p identtab[ITABSIZE];
+
+#define LOOKUP 0
+#define HALFWAY 1
+#define ENTER 2
+#define JUSTLOOKING 3
+
+
+typedef struct expr {
+ int expr_typ;
+# define TYPINT 1
+# define TYPREG 2
+# define TYPSTR 3
+# define TYPBOOL 4
+ int expr_index;
+} expr_t,*expr_p;
+
+extern unsigned cc1 INIT(1),cc2 INIT(1),cc3 INIT(1),cc4 INIT(1);
+
+extern node_t nodes[MAXNODES];
+extern node_p lastnode INIT(nodes+1);
+
+extern string codestrings[MAXSTRINGS];
+extern int ncodestrings;
+
+extern int strar[MAXNSTR];
+extern int nstr;
+
+extern int pathash[256];
+
+extern reginfo machregs[MAXREGS];
+extern char stregclass[MAXREGS];
+extern int nmachregs INIT(1);
+extern int nregclasses INIT(1);
+extern int maxmembers;
+extern struct {
+ ident_p propname;
+ set_t propset;
+} machprops[MAXPROPS];
+extern int nprops;
+extern token_t machtokens[MAXTOKENS];
+extern int nmachtokens INIT(1);
+extern set_t machsets[MAXSETS];
+extern int nmachsets;
+extern int patmnem[MAXEMPATLEN];
+extern int empatlen;
+extern int maxempatlen;
+extern int empatexpr;
+extern int maxrule INIT(1);
+extern int pattokexp[MAXPATLEN];
+extern int tokpatlen;
+extern int lookident; /* lexical analyzer flag */
+extern list3 structpool;
+extern int nallreg;
+extern int allreg[MAXALLREG];
+extern int maxallreg;
+extern int lino;
+extern int nerrors;
+extern int curtokexp;
+extern expr_t arexp[TOKENSIZE];
+extern int narexp;
+extern inst_t arinstance[MAXINSTANCE];
+extern int narinstance INIT(1);
+extern move_t machmoves[NMOVES];
+extern int nmoves;
+extern byte pattern[MAXPATTERN];
+extern int npatbytes;
+extern int prevind;
+extern int rulecount; /* Temporary index for ... construct */
+extern int ncoderules;
+extern int codebytes;
+extern FILE *cfile;
+extern FILE *hfile;
+extern int maxtokensize;
+extern int dealflag;
+extern int emrepllen;
+extern int replmnem[MAXEMPATLEN];
+extern int tokrepllen;
+extern int replinst[MAXPATLEN];
+extern int replexpr[MAXPATLEN];
+extern c1_t c1coercs[MAXC1];
+extern c2_t c2coercs[MAXC2];
+extern c3_t c3coercs[MAXC3];
+extern int nc1,nc2,nc3;
+extern int maxsplit;
+extern int wsize INIT(-1);
+extern int psize INIT(-1);
+extern int bsize INIT(-1);
+extern char *fmt;
+
+extern int cchandled;
+extern int ccspoiled;
+extern int ccregexpr;
+extern int ccinstanceno;
+extern int cocopropno;
+extern int cocosetno;
+extern int allexpno;
+
+extern int rvused; /* regvars used */
+extern int nregvar[4]; /* # of register variables of all kinds */
+extern int rvnumbers[4][MAXREGVARS]; /* The register numbers */
+
+#define chktabsiz(size,maxsize,which) if(size>=maxsize) tabovf(which)
+
+#define MUST1BEINT(e) int exp1=e.expr_index;tstint(e)
+#define MUST2BEINT(e1,e2) int exp1=e1.expr_index,exp2=e2.expr_index;tstint(e1);tstint(e2)
+#define MUST1BEBOOL(e) int exp1=e.expr_index;tstbool(e)
+#define MUST2BEBOOL(e1,e2) int exp1=e1.expr_index,exp2=e2.expr_index;tstbool(e1);tstbool(e2)
+
+extern ident_p ilookup();
+extern list2 lookstruct();
+extern string scopy();
+extern unsigned hash();
#undef unput
#define MAXBACKUP 50
+
+#include "booth.h"
+#include "y.tab.h"
%}
%p 2000
--- /dev/null
+#include "booth.h"
+
+char *strncpy(), strcpy(), sprintf();
+
+char * myalloc(n) {
+ register char *p;
+
+ p= (char*) malloc((unsigned)n);
+ if (p==0) {
+ yyerror("Out of core");
+ exit(1);
+ }
+ return(p);
+}
+
+tstint(e) expr_t e; {
+
+ if(e.expr_typ != TYPINT)
+ yyerror("Must be integer expression");
+}
+
+tstbool(e) expr_t e; {
+
+ if(e.expr_typ != TYPBOOL)
+ yyerror("Must be boolean expression");
+}
+
+structsize(s) register list2 s; {
+ register list1 l;
+ register sum;
+
+ sum = 0;
+ while ( s != 0 ) {
+ l = s->l2list->l1next;
+ while ( l != 0 ) {
+ sum++;
+ l = l->l1next;
+ }
+ s = s->l2next;
+ }
+ return(sum);
+}
+
+list2 lookstruct(ll) list2 ll; {
+ list3 l3;
+ 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)
+ ;
+ if (l11!=0 || l12!=0)
+ goto contin;
+ }
+ if(l21==0 && l22==0)
+ return(l3->l3list);
+ contin:;
+ }
+ l3 = (list3) myalloc(sizeof(struct list3str));
+ l3->l3next=structpool;
+ l3->l3list=ll;
+ structpool=l3;
+ return(ll);
+}
+
+instno(inst) inst_t inst; {
+ register i,j;
+
+ for(i=1;i<narinstance;i++) {
+ if (arinstance[i].in_which != inst.in_which)
+ continue;
+ for(j=0;j<TOKENSIZE;j++)
+ if(arinstance[i].in_info[j] != inst.in_info[j])
+ goto cont;
+ return(i);
+ cont:;
+ }
+ chktabsiz(narinstance,MAXINSTANCE,"Instance table");
+ arinstance[narinstance] = inst;
+ return(narinstance++);
+}
+
+string scopy(s) string s; {
+ register string t;
+
+ t = (char *) myalloc(strlen(s)+1);
+ strcpy(t,s);
+ return(t);
+}
+
+strlookup(s) string s; {
+ register i;
+
+ for(i=0;i<ncodestrings;i++)
+ if(strcmp(s,codestrings[i])==0)
+ return(i);
+ chktabsiz(ncodestrings,MAXSTRINGS,"string table");
+ codestrings[ncodestrings] = scopy(s);
+ return(ncodestrings++);
+}
+
+stringno(s) register string s; {
+ char buf[256];
+ register char *p=buf;
+
+ while(*s != 0) switch(*s) {
+ default:
+ *p++ = *s++;
+ continue;
+ case '$':
+ s++;
+ 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++;
+ 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;
+ }
+ }
+ } 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;
+ return(strlookup(buf));
+}
+
+tabovf(tablename) string tablename; {
+ char buf[256];
+
+ sprintf(buf,"%s overflow",tablename);
+ yyerror(buf);
+ exit(-1);
+}
+
+main(argc,argv) char *argv[]; {
+
+ while (--argc) {
+ ++argv;
+ 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;
+ }
+ } else {
+ iname= argv[0];
+ }
+ }
+ inithash();
+ initio();
+ inittables();
+ yyparse();
+ if (nerrors==0) {
+ compueq();
+ hashpatterns();
+ finishio();
+ verbose();
+ }
+ debug();
+ exit(nerrors);
+}
+
+lookup(comm,operator,lnode,rnode) {
+ register node_p p;
+
+ for (p=nodes+1;p<lastnode;p++) {
+ if (p->ex_operator != operator)
+ continue;
+ if (!(p->ex_lnode == lnode && p->ex_rnode == rnode ||
+ comm && p->ex_lnode == rnode && p->ex_rnode == lnode))
+ continue;
+ return(p-nodes);
+ }
+ if (lastnode >= &nodes[MAXNODES])
+ yyerror("node table overflow");
+ lastnode++;
+ p->ex_operator = operator;
+ p->ex_lnode = lnode;
+ p->ex_rnode = rnode;
+ return(p-nodes);
+}
+
+compueq() {
+ register i,j;
+
+ for (i=1;i<nmachregs;i++) {
+ for (j=1;j<i;j++)
+ if (eqregclass(i,j)) {
+ stregclass[i] = stregclass[j];
+ break;
+ }
+ if (j==i)
+ stregclass[i] = nregclasses++;
+ }
+}
+
+eqregclass(r1,r2) {
+ register reginfo rp1,rp2;
+ register i;
+ short regbits[(MAXREGS+15)>>4];
+ int member;
+
+ rp1 = machregs[r1]; rp2 = machregs[r2];
+ for (i=0;i<((nprops+15)>>4);i++)
+ if (rp1->rprop[i] != rp2->rprop[i])
+ return(0);
+ for (i=0;i<((MAXREGS+15)>>4);i++)
+ regbits[i] = 0;
+ for (i=0;i<maxmembers;i++) {
+ if (member = rp1->rmembers[i])
+ regbits[member>>4] |= (1<<(member&017));
+ }
+ for (i=0;i<maxmembers;i++) {
+ member = rp2->rmembers[i];
+ if (regbits[member>>4]&(1<<(member&017)))
+ return(0);
+ }
+ return(1);
+}
+
+unsigned hash(name) register string name; {
+ register unsigned sum;
+ register i;
+
+ for (sum=i=0;*name;i+=3)
+ sum ^= (*name++)<<(i&07);
+ return(sum);
+}
+
+ident_p ilookup(name,enterf) string name; int enterf; {
+ register ident_p p,*pp;
+
+ pp = &identtab[hash(name)%ITABSIZE];
+ while (*pp != 0) {
+ if (strcmp((*pp)->i_name,name)==0)
+ if (enterf != ENTER)
+ return(*pp);
+ else
+ yyerror("Multiply defined symbol");
+ pp = &(*pp)->i_next;
+ }
+ if (enterf == LOOKUP)
+ yyerror("Undefined symbol");
+ if (enterf == JUSTLOOKING)
+ return(0);
+ p = *pp = (ident_p) myalloc(sizeof(ident_t));
+ p->i_name = name;
+ p->i_next = 0;
+ p->i_type = 0;
+ return(p);
+}
+
+initio() {
+
+ if (iname!=0 && freopen(iname,"r",stdin)==NULL) {
+ fprintf(stderr,"Can't open %s\n",iname);
+ exit(-1);
+ }
+ if ((cfile=fopen(cname,"w"))==NULL) {
+ fprintf(stderr,"Can't create %s\n",cname);
+ exit(-1);
+ }
+ if ((hfile=fopen(hname,"w"))==NULL) {
+ fprintf(stderr,"Can't create %s\n",hname);
+ exit(-1);
+ }
+ 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);
+}
+
+exprlookup(sett) set_t sett; {
+ register i,j,ok;
+
+ 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;
+ ok=0;
+ break;
+ }
+ if (ok)
+ return(i);
+ }
+ chktabsiz(nmachsets,MAXSETS,"Expression table");
+ machsets[nmachsets] = sett;
+ return(nmachsets++);
+}
+
+inittables() {
+ register reginfo r;
+ register i;
+ inst_t inst;
+ set_t sett;
+
+ 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;
+ r->rregvar= -1;
+ for(i=0;i<MAXMEMBERS;i++)
+ r->rmembers[i] = 0;
+ for(i=0;i<PROPSETSIZE;i++)
+ r->rprop[i] = 0;
+ r->rprop[cocopropno>>4] |= (1<<(cocopropno&017));
+ chktabsiz(nmachregs,MAXREGS,"Register table");
+ machregs[nmachregs++] = r;
+ inst.in_which = IN_RIDENT;
+ 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);
+}
+
+outregs() {
+ register 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.
+ */
+ 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);
+ 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);
+ fprintf(cfile,"},{");
+ for (j=0;j<((nmachregs+15)>>4);j++)
+ fprintf(cfile,"%d,",rset[j]);
+ fprintf(cfile,"}");
+ }
+ if (machregs[i]->rregvar>=0)
+ fprintf(cfile,",1");
+ fprintf(cfile,"},\n");
+ }
+ fprintf(cfile,"};\n\n");
+}
+
+finishio() {
+ register i;
+ register node_p np;
+ int j;
+ int setsize;
+ register move_p mp;
+
+ fprintf(cfile,"};\n\n");
+ if (wsize>0)
+ fprintf(hfile,"#define TEM_WSIZE %d\n",wsize);
+ else
+ yyerror("Wordsize undefined");
+ if (psize>0)
+ fprintf(hfile,"#define TEM_PSIZE %d\n",psize);
+ else
+ yyerror("Pointersize undefined");
+ if (bsize>=0)
+ fprintf(hfile,"#define TEM_BSIZE %d\n",bsize);
+ else
+ yyerror("EM_BSIZE undefined");
+ 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();
+ 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);
+ fprintf(cfile,"};\n\nstring codestrings[] = {\n");
+ for(i=0;i<ncodestrings;i++) {
+ register char *p;
+ p=codestrings[i];
+ fprintf(cfile,"\t\"");
+ while (*p) {
+ register int c = (*p) & BMASK;
+ if (! isascii(c) || iscntrl(c)) {
+ fprintf(cfile,"\\%c%c%c",((c>>6) &03)+'0',
+ ((c>>3)&07)+'0',(c&07)+'0');
+ }
+ else putc(c, cfile);
+ p++;
+ }
+ 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]);
+ 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];
+ 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)
+ 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);
+ }
+ fprintf(cfile,"\t0\n};\n");
+ }
+ fprintf(cfile,"struct reginfo **reglist[] = {\n");
+ for (i=0;i<nprops;i++) {
+ fprintf(cfile,"\trlist%d,\n",i);
+ }
+ 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();
+}
+
+outregvar() {
+ register 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
+ 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
+ fprintf(cfile,"\t0,\n");
+ fprintf(cfile,"};\n");
+}
+
+verbose() {
+
+ 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);
+}
+
+inbetween() {
+ register ident_p ip;
+ register i,j;
+ register move_p mp;
+
+ lookident=1; /* for lexical analysis */
+
+ chktabsiz(nmachsets+1,MAXSETS,"Expressiontable");
+ for (i=0;i<SETSIZE;i++)
+ machsets[nmachsets].set_val[i] = 0xFFFF;
+ machsets[nmachsets].set_val[0] &= ~1;
+ machsets[nmachsets].set_size = 0;
+ ip=ilookup("SCRATCH",ENTER);
+ ip->i_type=IEXP;
+ ip->i_i.i_expno = nmachsets++;
+
+ for (i=0;i<SETSIZE;i++)
+ machsets[nmachsets].set_val[i] = 0xFFFF;
+ machsets[nmachsets].set_size = 0;
+ 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;
+ 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
+ */
+
+ for (i=0;i<nprops;i++) {
+ short *sp = machprops[i].propset.set_val;
+
+ sp[0] |= 1;
+ for (j=2;j<=nmachregs;j++)
+ if (machregs[j-1]->rprop[i>>4]&(1<<(i&017)))
+ sp[j>>4] |= (1<<(j&017));
+ }
+}
+
+formconversion(p,tp) register char *p; register token_p tp; {
+ char buf[256];
+ register char *q=buf;
+ char field[256];
+ register char *f;
+ int i;
+
+ 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;
+ return(strlookup(buf));
+}
+
+setfields(tp,format) register token_p tp; string format; {
+ register i;
+ list2 ll;
+ register list1 l;
+ int type;
+
+ for(i=0;i<TOKENSIZE-1;i++)
+ tp->t_fields[i].t_type = 0;
+ i=0;
+ for(ll=tp->t_struct;ll!=0;ll=ll->l2next) {
+ l=ll->l2list;
+ if(strcmp(l->l1name,"REGISTER")==0)
+ type = TYPREG;
+ else if (strcmp(l->l1name,"INT")==0)
+ type = TYPINT;
+ 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)
+ tp->t_format = formconversion(format,tp);
+ else
+ tp->t_format = -1;
+}
+
+chkregexp(number) {
+ register i;
+
+ 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");
+}
+
+findstructel(number,name,t) string name; int *t; {
+ register i;
+ register token_p tp;
+ register list2 structdecl;
+ int offset;
+
+ 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;
+ 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");
+ }
+ }
+ if (structdecl == 0) {
+ yyerror("No structs in this set");
+ return(0);
+ }
+ 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;
+ return(offset+1);
+ }
+ yyerror("No such field in this struct");
+ return(0);
+}
+
+extern char em_flag[];
+
+argtyp(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);
+ }
+}
+
+commontype(e1,e2) expr_t e1,e2; {
+
+ if(e1.expr_typ != e2.expr_typ)
+ yyerror("Type incompatibility");
+ return(e1.expr_typ);
+}
+
+extern char em_mnem[][4];
+
+#define HASHSIZE (2*(sp_lmnem-sp_fmnem))
+
+struct hashmnem {
+ char h_name[3];
+ byte h_value;
+} hashmnem[HASHSIZE];
+
+inithash() {
+ register i;
+
+ for(i=0;i<=sp_lmnem-sp_fmnem;i++)
+ enter(em_mnem[i],i+sp_fmnem);
+}
+
+enter(name,value) char *name; {
+ register unsigned h;
+
+ h=hash(name)%HASHSIZE;
+ while (hashmnem[h].h_name[0] != 0)
+ h = (h+1)%HASHSIZE;
+ strncpy(hashmnem[h].h_name,name,3);
+ hashmnem[h].h_value = value;
+}
+
+int mlookup(name) char *name; {
+ register unsigned h;
+
+ 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 */
+}
+
+hashpatterns() {
+ short index;
+ register byte *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;
+ }
+}
+
+debug() {
+ register i,j;
+
+ for(i=0;i<ITABSIZE;i++) {
+ register ident_p ip;
+ 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);
+ }
+
+ for(i=2;i<nmachregs;i++) {
+ register reginfo rp;
+
+ 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(")");
+ for(j=0;j<nprops;j++)
+ if(rp->rprop[j>>4]&(1<<(j&017)))
+ printf(", %s",machprops[j].propname->i_name);
+ printf(".\n");
+ }
+}
+
+out(n) {
+
+ assert(n>=0);
+ if (n<128)
+ outbyte(n);
+ else {
+ outbyte(n/256+128);
+ outbyte(n%256);
+ }
+}
+
+outbyte(n) {
+
+ fprintf(cfile,"%d, ",n&BMASK);
+ codebytes++;
+}
+
+pat(n) {
+
+ assert(n>=0);
+ if (n<128)
+ patbyte(n);
+ else {
+ patbyte(n/256+128);
+ patbyte(n%256);
+ }
+}
+
+patshort(n) {
+
+ patbyte(n&BMASK);
+ patbyte(n>>BSHIFT);
+}
+
+patbyte(n) {
+
+ chktabsiz(npatbytes,MAXPATTERN,"Pattern table");
+ pattern[npatbytes++] = n;
+}
+
+max(a,b) {
+
+ if (a>b)
+ return(a);
+ return(b);
+}