--- /dev/null
+/* $Header$ */
+
+#ifndef NDEBUG
+#define assert(x) if(!(x)) badassertion("x",__FILE__,__LINE__)
+#else
+#define assert(x) /* nothing */
+#endif
--- /dev/null
+#ifndef NORCSID
+static char rcsid[] = "$Header$";
+#endif
+
+#include "assert.h"
+#include "param.h"
+#include "tables.h"
+#include "types.h"
+#include <cgg_cg.h>
+#include "data.h"
+#include "result.h"
+#include "state.h"
+#include "equiv.h"
+#include "extern.h"
+
+/*
+ * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ *
+ * This product is part of the Amsterdam Compiler Kit.
+ *
+ * Permission to use, sell, duplicate or disclose this software must be
+ * obtained in writing. Requests for such permissions may be sent to
+ *
+ * Dr. Andrew S. Tanenbaum
+ * Wiskundig Seminarium
+ * Vrije Universiteit
+ * Postbox 7161
+ * 1007 MC Amsterdam
+ * The Netherlands
+ *
+ * Author: Hans van Staveren
+ */
+
+#define ALLOW_NEXTEM /* code generator is allowed new try of NEXTEM
+ in exceptional cases */
+
+#define MAXPATTERN 5
+#define MAXREPLLEN 5 /* Max length of EM-replacement, should come from boot */
+
+byte startupcode[] = { DO_NEXTEM };
+
+byte *nextem();
+unsigned costcalc();
+unsigned docoerc();
+unsigned stackupto();
+string tostring();
+string ad2str();
+
+#ifdef NDEBUG
+#define DEBUG(string)
+#else
+#include <stdio.h>
+#define DEBUG(string) {if(Debug) fprintf(stderr,"%-*d%s\n",4*level,level,string);}
+#endif
+
+#define BROKE() {assert(origcp!=startupcode);DEBUG("BROKE");totalcost=INFINITY;goto doreturn;}
+#define CHKCOST() {if (totalcost>=costlimit) BROKE();}
+
+#ifdef TABLEDEBUG
+int tablelines[MAXTDBUG];
+int ntableline;
+int set_fd,set_size;
+short *set_val;
+char *set_flag;
+#endif
+
+unsigned codegen(codep,ply,toplevel,costlimit,forced) byte *codep; unsigned costlimit; {
+#ifndef NDEBUG
+ byte *origcp=codep;
+ static int level=0;
+#endif
+ unsigned totalcost = 0;
+ int inscoerc=0;
+ int procarg[2];
+#ifdef ALLOW_NEXTEM
+ int paniced;
+ char *savebp;
+#endif
+ state_t state;
+#define SAVEST savestatus(&state)
+#define RESTST restorestatus(&state)
+#define FREEST /* nothing */
+#ifdef TABLEDEBUG
+ extern char *tablename;
+#endif
+
+#ifndef NDEBUG
+ level++;
+ DEBUG("Entering codegen");
+#endif
+ for (;;) {
+ switch( (*codep++)&037 ) {
+ default:
+ assert(FALSE);
+ /* NOTREACHED */
+#ifdef TABLEDEBUG
+ case DO_DLINE: {
+ int n;
+
+ getint(n,codep);
+ tablelines[ntableline++] = n;
+ if (ntableline>=MAXTDBUG)
+ ntableline -= MAXTDBUG;
+ if (set_fd)
+ set_val[n>>4] &= ~(1<<(n&017));
+#ifndef NDEBUG
+ if (Debug)
+ fprintf(stderr,"code from \"%s\", line %d\n",tablename,n);
+#endif
+ break;
+ }
+#endif
+ case DO_NEXTEM: {
+ byte *bp;
+ int n;
+ unsigned mindistance,dist;
+ register i;
+ int cindex;
+ int npos,pos[MAXRULE];
+ unsigned mincost,t;
+
+ DEBUG("NEXTEM");
+ tokpatlen = 0;
+ nallreg=0;
+ if (toplevel) {
+ garbage_collect();
+ totalcost=0;
+ } else {
+ if (--ply <= 0)
+ goto doreturn;
+ }
+ if (stackheight>MAXFSTACK-7) {
+#ifndef NDEBUG
+ if (Debug)
+ fprintf(stderr,"Fakestack overflow threatens(%d), action ...\n",stackheight);
+#endif
+ totalcost += stackupto(&fakestack[6],ply,toplevel);
+ }
+#ifndef ALLOW_NEXTEM
+ bp = nextem(toplevel);
+#else
+ paniced=0;
+ savebp = nextem(toplevel);
+ panic:
+ bp = savebp;
+#endif
+ if (bp == 0) {
+ /*
+ * No pattern found, can be pseudo or error
+ * in table.
+ */
+ if (toplevel) {
+ codep--;
+ DEBUG("pseudo");
+ dopseudo();
+ } else
+ goto doreturn;
+ } else {
+#ifndef NDEBUG
+ chkregs();
+#endif
+ n = *bp++;
+ if (n==0) { /* "procedure" */
+ getint(i,bp);
+ getint(procarg[0],bp);
+ getint(procarg[1],bp);
+ bp= &pattern[i];
+ n = *bp++;
+ DEBUG("PROC_CALL");
+ }
+ assert(n>0 && n<=MAXRULE);
+ if (n>1) {
+ mindistance = MAXINT; npos=0;
+ for(i=0;i<n;i++) {
+ getint(cindex,bp);
+ dist=distance(cindex);
+#ifndef NDEBUG
+if (Debug)
+ fprintf(stderr,"distance of pos %d is %u\n",i,dist);
+#endif
+ if (dist<=mindistance) {
+ if (dist<mindistance) {
+ if(dist==0)
+ goto gotit;
+ npos=0;
+ mindistance = dist;
+ }
+ pos[npos++] = cindex;
+ }
+ }
+ assert(mindistance<MAXINT);
+ if (npos>1) {
+ /*
+ * More than 1 tokenpattern is a candidate.
+ * Decision has to be made by lookahead.
+ */
+ SAVEST;
+ mincost = costlimit-totalcost+1;
+ for(i=0;i<npos;i++) {
+ t=codegen(&coderules[pos[i]],ply,FALSE,mincost,0);
+#ifndef NDEBUG
+if (Debug)
+ fprintf(stderr,"mincost %u,cost %u,pos %d\n",mincost,t,i);
+#endif
+ if (t<mincost) {
+ mincost = t;
+ cindex = pos[i];
+ }
+ RESTST;
+ }
+ FREEST;
+ if (totalcost+mincost>costlimit)
+ BROKE();
+ } else {
+ cindex = pos[0];
+ }
+ } else {
+ getint(cindex,bp);
+ }
+
+ gotit:
+ /*
+ * Now cindex contains the code-index of the best candidate
+ * so proceed to use it.
+ */
+ codep = &coderules[cindex];
+ }
+ break;
+ }
+ case DO_COERC: {
+ DEBUG("COERC");
+ tokpatlen=1;
+ inscoerc=1;
+ break;
+ }
+ case DO_XXMATCH:
+ DEBUG("XXMATCH");
+ case DO_XMATCH: {
+ register i;
+ int temp;
+
+ DEBUG("XMATCH");
+ tokpatlen=(codep[-1]>>5)&07;
+ for (i=0;i<tokpatlen;i++)
+ getint(temp,codep);
+ break; /* match already checked by distance() */
+ }
+ case DO_MATCH: {
+ register i;
+ int j;
+ unsigned mincost,t;
+ token_p tp;
+ int size,lsize;
+ int tokexp[MAXPATTERN];
+ int nregneeded;
+ token_p regtp[MAXCREG];
+ c3_p regcp[MAXCREG];
+ rl_p regls[MAXCREG];
+ c3_p cp,findcoerc();
+ int sret;
+ int stackpad;
+ struct perm *tup,*ntup,*besttup,*tuples();
+
+ DEBUG("MATCH");
+ tokpatlen=(codep[-1]>>5)&07;
+ for(i=0;i<tokpatlen;i++)
+ getint(tokexp[i],codep);
+ tokexp[i] = 0;
+ tp = &fakestack[stackheight-1];
+ i=0;
+ while (i<tokpatlen && tp>=fakestack) {
+ size=tsize(tp);
+ while (i<tokpatlen && (lsize=ssize(tokexp[i]))<=size) {
+ size -= lsize;
+ i++;
+ }
+ if (i<tokpatlen && size!=0) {
+ totalcost += stackupto(tp,ply,toplevel);
+ CHKCOST();
+ break;
+ }
+ tp--;
+ }
+ tp = &fakestack[stackheight-1];
+ i=0;
+ while (i<tokpatlen && tp >= fakestack) {
+ size = tsize(tp);
+ lsize= ssize(tokexp[i]);
+ if (size != lsize) { /* find coercion */
+#ifdef MAXSPLIT
+ sret = split(tp,&tokexp[i],ply,toplevel);
+ if (sret==0) {
+#endif MAXSPLIT
+ totalcost += stackupto(tp,ply,toplevel);
+ CHKCOST();
+ break;
+#ifdef MAXSPLIT
+ }
+ i += sret;
+#endif MAXSPLIT
+ } else
+ i += 1;
+ tp--;
+ }
+ nextmatch:
+ tp = &fakestack[stackheight-1];
+ i=0; nregneeded = 0;
+ while (i<tokpatlen && tp>=fakestack) {
+ if (!match(tp,&machsets[tokexp[i]],0)) {
+ cp = findcoerc(tp, &machsets[tokexp[i]]);
+#ifndef NDEBUG
+if (Debug>1) fprintf(stderr,"findcoerc returns %d at position %d\n",cp,i);
+#endif
+ if (cp==0) {
+ for (j=0;j<nregneeded;j++)
+ regtp[j] -= (tp-fakestack+1);
+ totalcost += stackupto(tp,ply,toplevel);
+ CHKCOST();
+ break;
+ } else {
+ if (cp->c3_prop==0) {
+ totalcost+=docoerc(tp,cp,ply,toplevel,0);
+ CHKCOST();
+ } else {
+#ifndef NDEBUG
+if(Debug>1) fprintf(stderr,"Register of type %d needed, remembering...\n",cp->c3_prop);
+#endif
+ assert(nregneeded<MAXCREG);
+ regtp[nregneeded] = tp;
+ regcp[nregneeded] = cp;
+ regls[nregneeded] = curreglist;
+ nregneeded++;
+ }
+ }
+ }
+ i++; tp--;
+ }
+ if (tokpatlen>stackheight) {
+#ifndef NDEBUG
+if(Debug>1) fprintf(stderr,"Pattern too long, %d with only %d items on stack\n",
+ tokpatlen,stackheight);
+#endif
+ stackpad = tokpatlen-stackheight;
+ for (j=stackheight-1;j>=0;j--)
+ fakestack[j+stackpad] = fakestack[j];
+ for (j=0;j<stackpad;j++)
+ fakestack[j].t_token=0;
+ stackheight += stackpad;
+ for (j=0;j<nregneeded;j++)
+ regtp[j] += stackpad;
+ for (tp = &fakestack[stackpad-1];i<tokpatlen && tp>=fakestack;i++,tp--) {
+ cp = findcoerc((token_p) 0, &machsets[tokexp[i]]);
+ if (cp==0) {
+ for (j=0;j<nregneeded;j++)
+ myfree(regls[j]);
+#ifndef ALLOW_NEXTEM
+ assert(!toplevel);
+ BROKE();
+#else
+ assert(!(toplevel&&paniced));
+ goto normalfailed;
+#endif
+ }
+ if (cp->c3_prop==0) {
+ totalcost+=docoerc(tp,cp,ply,toplevel,0);
+ CHKCOST();
+ } else {
+ assert(nregneeded<MAXCREG);
+ regtp[nregneeded] = tp;
+ regcp[nregneeded] = cp;
+ regls[nregneeded] = curreglist;
+ nregneeded++;
+ }
+ }
+ } else
+ stackpad=0;
+ assert(i==tokpatlen);
+ if (nregneeded==0)
+ break;
+ SAVEST;
+ mincost=costlimit-totalcost+1;
+ tup = tuples(regls,nregneeded);
+ besttup=0;
+ for (; tup != 0; tup = ntup) {
+#ifndef NDEBUG
+if(Debug>1) fprintf(stderr,"Next tuple %d,%d,%d,%d\n",
+ tup->p_rar[0],
+ tup->p_rar[1],
+ tup->p_rar[2],
+ tup->p_rar[3]);
+#endif
+ ntup = tup->p_next;
+ for (i=0,t=0;i<nregneeded && t<mincost; i++)
+ t += docoerc(regtp[i],regcp[i],ply,FALSE,tup->p_rar[i]);
+ if (t<mincost) {
+#ifndef NDEBUG
+ if (Debug>2)
+ fprintf(stderr,"Continuing match after coercions\n");
+#endif
+ t += codegen(codep,ply,FALSE,mincost-t,0);
+ }
+ if (t<mincost) {
+ mincost = t;
+ besttup = tup;
+ } else
+ myfree(tup);
+ RESTST;
+ }
+ FREEST;
+ for (i=0;i<nregneeded;i++)
+ myfree(regls[i]);
+ if (totalcost+mincost>costlimit) {
+ if (besttup)
+ myfree(besttup);
+normalfailed: if (stackpad!=tokpatlen) {
+ if (stackpad) {
+ if (costlimit<MAXINT)
+ BROKE();
+ for (i=0;i<stackheight-stackpad;i++)
+ fakestack[i] = fakestack[i+stackpad];
+ stackheight -= stackpad;
+ totalcost += stackupto(&fakestack[stackheight-1],ply,toplevel);
+ } else
+ totalcost += stackupto(fakestack,ply,toplevel);
+ CHKCOST();
+ goto nextmatch;
+ }
+ totalcost += mincost;
+#ifndef ALLOW_NEXTEM
+ BROKE();
+#else
+ if (toplevel && !paniced) {
+ stackheight=0;
+ paniced++;
+ DEBUG("PANIC!");
+ goto panic;
+ } else
+ BROKE();
+#endif
+ }
+ for (i=0;i<nregneeded;i++)
+ totalcost += docoerc(regtp[i],regcp[i],ply,toplevel,besttup->p_rar[i]);
+ myfree(besttup);
+ break;
+ }
+ case DO_REMOVE: {
+ int texpno,nodeno;
+ token_p tp;
+ struct reginfo *rp;
+
+ DEBUG("REMOVE");
+ if (codep[-1]&32) {
+ getint(texpno,codep);
+ getint(nodeno,codep);
+ } else {
+ getint(texpno,codep);
+ nodeno=0;
+ }
+ for (tp= &fakestack[stackheight-tokpatlen-1];tp>=&fakestack[0];tp--)
+ if (match(tp,&machsets[texpno],nodeno)) {
+ /* investigate possible coercion to register */
+ totalcost += stackupto(tp,ply,toplevel);
+ CHKCOST();
+ break;
+ }
+ for (rp=machregs;rp<machregs+NREGS;rp++)
+ if (match(&rp->r_contents,&machsets[texpno],nodeno))
+ rp->r_contents.t_token=0;
+ break;
+ }
+ case DO_RREMOVE: { /* register remove */
+ register i;
+ int nodeno;
+ token_p tp;
+ tkdef_p tdp;
+ result_t result;
+
+ getint(nodeno,codep);
+ result=compute(&enodes[nodeno]);
+ assert(result.e_typ==EV_REG);
+ for (tp= &fakestack[stackheight-tokpatlen-1];tp>=&fakestack[0];tp--)
+ if (tp->t_token==-1) {
+ if(tp->t_att[0].ar==result.e_v.e_reg)
+ goto gotone;
+ } else {
+ tdp = &tokens[tp->t_token];
+ for(i=0;i<TOKENSIZE;i++)
+ if (tdp->t_type[i]==EV_REG &&
+ tp->t_att[i].ar==result.e_v.e_reg)
+ goto gotone;
+ }
+ break;
+ gotone:
+ /* investigate possible coercion to register */
+ totalcost += stackupto(tp,ply,toplevel);
+ CHKCOST();
+ break;
+ }
+ case DO_DEALLOCATE: {
+ register i;
+ tkdef_p tdp;
+ int tinstno;
+ token_t token;
+
+ DEBUG("DEALLOCATE");
+ getint(tinstno,codep);
+ instance(tinstno,&token);
+ if (token.t_token==-1)
+ chrefcount(token.t_att[0].ar,-1,TRUE);
+ else {
+ tdp= &tokens[token.t_token];
+ for (i=0;i<TOKENSIZE;i++)
+ if (tdp->t_type[i]==EV_REG)
+ chrefcount(token.t_att[i].ar,-1,TRUE);
+ }
+ break;
+ }
+ case DO_REALLOCATE: {
+ struct reginfo *rp;
+
+ DEBUG("REALLOCATE");
+ for(rp=machregs+1;rp<machregs+NREGS;rp++)
+ if(rp->r_tcount) {
+ rp->r_refcount -= rp->r_tcount;
+ rp->r_tcount = 0;
+ }
+ break;
+ }
+ case DO_ALLOCATE: {
+ register i;
+ int j;
+ int tinstno;
+ int npos,npos2,pos[NREGS],pos2[NREGS];
+ unsigned mincost,t;
+ struct reginfo *rp,**rpp;
+ token_t token,mtoken,token2;
+ int propno;
+ int exactmatch;
+ int decision;
+
+ if (codep[-1]&32) {
+ getint(propno,codep);
+ getint(tinstno,codep);
+ DEBUG("ALLOCATE,INIT");
+ } else {
+ getint(propno,codep);
+ tinstno=0;
+ DEBUG("ALLOCATE,EMPTY");
+ }
+ instance(tinstno,&token);
+ if (!forced) {
+ do {
+ npos=exactmatch=0;
+ for(rpp=reglist[propno];rp= *rpp; rpp++)
+ if (getrefcount(rp-machregs)==0) {
+ pos[npos++] = rp-machregs;
+ if (eqtoken(&rp->r_contents,&token))
+ exactmatch++;
+ }
+ /*
+ * Now pos[] contains all free registers with desired
+ * property. If none then some stacking has to take place.
+ */
+ if (npos==0) {
+ if (stackheight<=tokpatlen) {
+ if (!toplevel) {
+ BROKE();
+ } else
+ fatal("No regs available");
+ }
+ totalcost += stackupto( &fakestack[0],ply,toplevel);
+ CHKCOST();
+ }
+ } while (npos==0);
+ if (!exactmatch) {
+ npos2=npos;
+ for(i=0;i<npos;i++)
+ pos2[i]=pos[i];
+ } else {
+ /*
+ * Now we are reducing the number of possible registers.
+ * We take only one equally likely register out of every
+ * equivalence class as given by set of properties.
+ */
+ mtoken = token;
+ npos2=0;
+ for(i=0;i<npos;i++)
+ if (eqtoken(&machregs[pos[i]].r_contents,&mtoken)) {
+ pos2[npos2++] = pos[i];
+ for(j=0;j<npos2-1;j++)
+ if (eqregclass(pos2[j],pos[i])) {
+ npos2--;
+ break;
+ }
+ }
+ }
+ /*
+ * Now pos2[] contains all possibilities to try, if more than
+ * one, lookahead is necessary.
+ */
+ token2.t_token= -1;
+ for (i=1;i<TOKENSIZE;i++)
+ token2.t_att[i].aw=0;
+ if (npos2==1)
+ decision=pos2[0];
+ else {
+ SAVEST;
+ mincost=costlimit-totalcost+1;
+ for(j=0;j<npos2;j++) {
+ chrefcount(pos2[j],1,FALSE);
+ token2.t_att[0].ar=pos2[j];
+ allreg[nallreg++] = pos2[j];
+ if (token.t_token != 0)
+ t=move(&token,&token2,ply,FALSE,mincost);
+ else {
+ t = 0;
+ erasereg(pos2[j]);
+ }
+ if (t<mincost)
+ t += codegen(codep,ply,FALSE,mincost-t,0);
+ if (t<mincost) {
+ mincost=t;
+ decision=pos2[j];
+ }
+ RESTST;
+ }
+ FREEST;
+ if (totalcost+mincost>costlimit)
+ BROKE();
+ }
+ } else {
+ decision = forced;
+ if (getrefcount(decision)!=0)
+ BROKE();
+ token2.t_token = -1;
+ }
+ chrefcount(decision,1,FALSE);
+ token2.t_att[0].ar=decision;
+ if (token.t_token != 0) {
+ totalcost+=move(&token,&token2,ply,toplevel,MAXINT);
+ CHKCOST();
+ } else
+ erasereg(decision);
+ allreg[nallreg++]=decision;
+ break;
+ }
+ case DO_INSTR: {
+ register i;
+ int n;
+ int tinstno;
+ token_t token;
+ int stringno;
+
+ DEBUG("INSTR");
+ n=((codep[-1]>>5)&07);
+ getint(stringno,codep);
+ if (toplevel) {
+ swtxt();
+ if (stringno>10000) {
+ assert(stringno== 10001 || stringno== 10002);
+ genstr(procarg[stringno-10001]);
+ } else
+ genstr(stringno);
+ }
+ for(i=0;i<n;i++) {
+ getint(tinstno,codep);
+ instance(tinstno,&token);
+ if (toplevel)
+ prtoken(&token,i==0 ? ' ' : ',');
+ if (token.t_token>0)
+ totalcost += tokens[token.t_token].t_cost.ct_space;
+ }
+ if (toplevel)
+ gennl();
+ break;
+ }
+ case DO_MOVE: {
+ int tinstno;
+ token_t token,token2;
+
+ DEBUG("MOVE");
+ getint(tinstno,codep);
+ instance(tinstno,&token);
+ getint(tinstno,codep);
+ instance(tinstno,&token2);
+ totalcost += move(&token,&token2,ply,toplevel,costlimit-totalcost+1);
+ CHKCOST();
+ break;
+ }
+ case DO_TEST: {
+ int tinstno;
+ token_t token;
+
+ DEBUG("TEST");
+ getint(tinstno,codep);
+ instance(tinstno,&token);
+ totalcost += test(&token,ply,toplevel,costlimit-totalcost+1);
+ CHKCOST();
+ break;
+ }
+ case DO_SETCC: {
+ int tinstno;
+ token_t token;
+
+ DEBUG("SETCC");
+ getint(tinstno,codep);
+ instance(tinstno,&token);
+ setcc(&token);
+ break;
+ }
+ case DO_ERASE: {
+ int nodeno;
+ result_t result;
+
+ DEBUG("ERASE");
+ getint(nodeno,codep);
+ result=compute(&enodes[nodeno]);
+ assert(result.e_typ!=EV_INT && result.e_typ!=EV_ADDR);
+ if (result.e_typ==EV_REG)
+ erasereg(result.e_v.e_reg);
+ break;
+ }
+ case DO_TOKREPLACE: {
+ register i;
+ int tinstno;
+ int repllen;
+ token_t reptoken[MAXREPLLEN];
+
+ DEBUG("TOKREPLACE");
+ assert(stackheight>=tokpatlen);
+ repllen=(codep[-1]>>5)&07;
+#ifndef NDEBUG
+ if (Debug>2)
+ fprintf(stderr,"Stackheight=%d, tokpatlen=%d, repllen=%d %s\n",
+ stackheight,tokpatlen,repllen,inscoerc ? "(inscoerc)":"");
+#endif
+ for(i=0;i<repllen;i++) {
+ getint(tinstno,codep);
+ instance(tinstno,&reptoken[i]);
+ tref(&reptoken[i],1);
+ }
+ for(i=0;i<tokpatlen;i++) {
+ if (!inscoerc)
+ tref(&fakestack[stackheight-1],-1);
+ stackheight--;
+ }
+ for (i=0;i<repllen;i++) {
+ assert(stackheight<MAXFSTACK);
+ fakestack[stackheight++] = reptoken[i];
+ }
+ for(i=0;i<nallreg;i++)
+ chrefcount(allreg[i],-1,FALSE);
+ break;
+ }
+ case DO_EMREPLACE: {
+ register i;
+ int j;
+ int nodeno;
+ result_t result;
+ int emrepllen,eminstr;
+
+ DEBUG("EMREPLACE");
+ emrepllen=(codep[-1]>>5)&07;
+ j=emp-emlines;
+ if (emrepllen>j) {
+ assert(nemlines+emrepllen-j<MAXEMLINES);
+ for (i=nemlines;i>=0;i--)
+ emlines[i+emrepllen-j] = emlines[i];
+ nemlines += emrepllen-j;
+ emp += emrepllen-j;
+ }
+ emp -= emrepllen;
+ for (i=0;i<emrepllen;i++) {
+ getint(eminstr,codep);
+ getint(nodeno,codep);
+ emp[i].em_instr = eminstr;
+ result = compute(&enodes[nodeno]);
+ switch(result.e_typ) {
+ default:
+ assert(FALSE);
+ case 0:
+ emp[i].em_optyp = OPNO;
+ emp[i].em_soper = 0;
+ break;
+ case EV_INT:
+ emp[i].em_optyp = OPINT;
+ emp[i].em_soper = tostring(result.e_v.e_con);
+ emp[i].em_u.em_ioper = result.e_v.e_con;
+ break;
+ case EV_ADDR:
+ emp[i].em_optyp = OPSYMBOL;
+ emp[i].em_soper = ad2str(result.e_v.e_addr);
+ break;
+ }
+ }
+ if (!toplevel)
+ ply += emrepllen;
+ break;
+ }
+ case DO_COST: {
+ cost_t cost;
+
+ DEBUG("COST");
+ getint(cost.ct_space,codep);
+ getint(cost.ct_time,codep);
+ totalcost += costcalc(cost);
+ CHKCOST();
+ break;
+ }
+#ifdef REGVARS
+ case DO_PRETURN: {
+ if (toplevel) {
+ swtxt();
+ regreturn(); /* in mach.c */
+ }
+ break;
+ }
+#endif
+ case DO_RETURN:
+ DEBUG("RETURN");
+ assert(origcp!=startupcode);
+ doreturn:
+#ifndef NDEBUG
+ level--;
+#endif
+ return(totalcost);
+ }
+ }
+}
+
+readcodebytes() {
+#ifndef CODEINC
+ register fd;
+ extern int ncodebytes;
+
+ if ((fd=open("code",0))<0) {
+ error("Can't open code");
+ }
+ if (read(fd,coderules,ncodebytes)!=ncodebytes) {
+ error("Short read from code");
+ }
+ close(fd);
+#endif
+}
+
+#ifdef TABLEDEBUG
+initlset(f) char *f; {
+ extern char *myalloc();
+
+ set_flag = f;
+ if ((set_fd=open(f+1,2))<0)
+ error("Can't open %s rw",f+1);
+ read(set_fd,&set_size,sizeof(int));
+ set_val=( short *) myalloc(set_size);
+ read(set_fd,set_val,set_size);
+}
+
+termlset() {
+
+ if (set_fd) {
+ lseek(set_fd,(long) sizeof(int),0);
+ write(set_fd,set_val,set_size);
+ close(set_fd);
+ if (set_flag[0]=='u') {
+ register i;
+
+ fprintf(stderr,"Unused code rules:\n\n");
+ for(i=0;i<8*set_size;i++)
+ if(set_val[i>>4]&(1<<(i&017)))
+ fprintf(stderr,"\"%s\", line %d\n",tablename,i);
+ }
+ }
+}
+#endif
--- /dev/null
+#ifndef NORCSID
+static char rcsid[] = "$Header$";
+#endif
+
+#include "assert.h"
+#include "param.h"
+#include "tables.h"
+#include "types.h"
+#include <cgg_cg.h>
+#include "data.h"
+#include "result.h"
+#include "glosym.h"
+#include "extern.h"
+
+/*
+ * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ *
+ * This product is part of the Amsterdam Compiler Kit.
+ *
+ * Permission to use, sell, duplicate or disclose this software must be
+ * obtained in writing. Requests for such permissions may be sent to
+ *
+ * Dr. Andrew S. Tanenbaum
+ * Wiskundig Seminarium
+ * Vrije Universiteit
+ * Postbox 7161
+ * 1007 MC Amsterdam
+ * The Netherlands
+ *
+ * Author: Hans van Staveren
+ */
+
+#define LLEAF 01
+#define LDEF 02
+#define RLEAF 04
+#define RDEF 010
+#define LLDEF LLEAF|LDEF
+#define RLDEF RLEAF|RDEF
+
+char opdesc[] = {
+ 0, /* EX_TOKFIELD */
+ 0, /* EX_ARG */
+ 0, /* EX_CON */
+ 0, /* EX_ALLREG */
+ LLDEF|RLDEF, /* EX_SAMESIGN */
+ LLDEF|RLDEF, /* EX_SFIT */
+ LLDEF|RLDEF, /* EX_UFIT */
+ 0, /* EX_ROM */
+ LLDEF|RLDEF, /* EX_NCPEQ */
+ LLDEF|RLDEF, /* EX_SCPEQ */
+ LLDEF|RLDEF, /* EX_RCPEQ */
+ LLDEF|RLDEF, /* EX_NCPNE */
+ LLDEF|RLDEF, /* EX_SCPNE */
+ LLDEF|RLDEF, /* EX_RCPNE */
+ LLDEF|RLDEF, /* EX_NCPGT */
+ LLDEF|RLDEF, /* EX_NCPGE */
+ LLDEF|RLDEF, /* EX_NCPLT */
+ LLDEF|RLDEF, /* EX_NCPLE */
+ LLDEF, /* EX_OR2 */
+ LLDEF, /* EX_AND2 */
+ LLDEF|RLDEF, /* EX_PLUS */
+ LLDEF|RLDEF, /* EX_CAT */
+ LLDEF|RLDEF, /* EX_MINUS */
+ LLDEF|RLDEF, /* EX_TIMES */
+ LLDEF|RLDEF, /* EX_DIVIDE */
+ LLDEF|RLDEF, /* EX_MOD */
+ LLDEF|RLDEF, /* EX_LSHIFT */
+ LLDEF|RLDEF, /* EX_RSHIFT */
+ LLDEF, /* EX_NOT */
+ LLDEF, /* EX_COMP */
+ 0, /* EX_COST */
+ 0, /* EX_STRING */
+ LLEAF, /* EX_DEFINED */
+ 0, /* EX_SUBREG */
+ LLDEF, /* EX_TOSTRING */
+ LLDEF, /* EX_UMINUS */
+ 0, /* EX_REG */
+ 0, /* EX_LOWW */
+ 0, /* EX_HIGHW */
+ LLDEF, /* EX_INREG */
+ LLDEF, /* EX_REGVAR */
+};
+
+string salloc(),strcpy(),strcat();
+
+string mycat(s1,s2) register string s1,s2; {
+ register string s;
+
+ if (s1==0) return(s2);
+ if (s2==0) return(s1);
+ s=salloc(strlen(s1)+strlen(s2)+1);
+ strcpy(s,s1);
+ strcat(s,"+");
+ strcat(s,s2);
+ return(s);
+}
+
+string mystrcpy(s) register string s; {
+ register string r;
+
+ r=salloc(strlen(s));
+ strcpy(r,s);
+ return(r);
+}
+
+char digstr[21][15];
+
+string tostring(n) register word n; {
+ char buf[25];
+
+ if (n>=-20 && n<=20 && (n&1)==0) {
+ if (digstr[(n>>1)+10][0]==0)
+ sprintf(digstr[(n>>1)+10],WRD_FMT,n);
+ return(digstr[(n>>1)+10]);
+ }
+ sprintf(buf,WRD_FMT,n);
+ return(mystrcpy(buf));
+}
+
+result_t undefres= {EV_UNDEF};
+
+result_t compute(node) register node_p node; {
+ result_t leaf1,leaf2,result;
+ register token_p tp;
+ int desc;
+ long mask,tmp;
+ int i,tmpreg;
+ glosym_p gp;
+
+ desc=opdesc[node->ex_operator];
+ if (desc&LLEAF) {
+ leaf1 = compute(&enodes[node->ex_lnode]);
+ if (desc&LDEF && leaf1.e_typ==EV_UNDEF)
+ return(undefres);
+ }
+ if (desc&RLEAF) {
+ leaf2 = compute(&enodes[node->ex_rnode]);
+ if (desc&RDEF && leaf2.e_typ==EV_UNDEF)
+ return(undefres);
+ }
+ result.e_typ=EV_INT;
+ switch(node->ex_operator) {
+ default: assert(FALSE);
+ case EX_TOKFIELD:
+ if (node->ex_lnode!=0)
+ tp = &fakestack[stackheight-node->ex_lnode];
+ else
+ tp = curtoken;
+ switch(result.e_typ = tokens[tp->t_token].t_type[node->ex_rnode-1]) {
+ default:
+ assert(FALSE);
+ case EV_INT:
+ result.e_v.e_con = tp->t_att[node->ex_rnode-1].aw;
+ break;
+ case EV_ADDR:
+ result.e_v.e_addr = tp->t_att[node->ex_rnode-1].aa;
+ break;
+ case EV_REG:
+ result.e_v.e_reg = tp->t_att[node->ex_rnode-1].ar;
+ break;
+ }
+ return(result);
+ case EX_ARG:
+ return(dollar[node->ex_lnode-1]);
+ case EX_CON:
+ result.e_typ = EV_INT;
+ result.e_v.e_con = ((long) node->ex_rnode << 16) | ((long)node->ex_lnode&0xffff);
+ return(result);
+ case EX_REG:
+ result.e_typ = EV_REG;
+ result.e_v.e_reg = node->ex_lnode;
+ return(result);
+ case EX_ALLREG:
+ result.e_typ = EV_REG;
+ result.e_v.e_reg = allreg[node->ex_lnode-1];
+#if MAXMEMBERS!=0
+ if (node->ex_rnode!=0)
+ result.e_v.e_reg = machregs[result.e_v.e_reg].
+ r_members[node->ex_rnode-1];
+#endif
+ return(result);
+ case EX_SAMESIGN:
+ assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
+ result.e_typ = EV_INT;
+ if (leaf1.e_v.e_con>=0)
+ result.e_v.e_con= leaf2.e_v.e_con>=0;
+ else
+ result.e_v.e_con= leaf2.e_v.e_con<0;
+ return(result);
+ case EX_SFIT:
+ assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
+ mask = 0xFFFFFFFFL;
+ for (i=0;i<leaf2.e_v.e_con-1;i++)
+ mask &= ~(1<<i);
+ tmp = leaf1.e_v.e_con&mask;
+ result.e_v.e_con = tmp==0||tmp==mask;
+ return(result);
+ case EX_UFIT:
+ assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
+ mask = 0xFFFFFFFFL;
+ for (i=0;i<leaf2.e_v.e_con;i++)
+ mask &= ~(1<<i);
+ result.e_v.e_con = (leaf1.e_v.e_con&mask)==0;
+ return(result);
+ case EX_ROM:
+ assert(node->ex_rnode>=0 &&node->ex_rnode<MAXROM);
+ leaf2=dollar[node->ex_lnode];
+ if (leaf2.e_typ != EV_ADDR)
+ return(undefres);
+ if (leaf2.e_v.e_addr.ea_off!=0)
+ return(undefres);
+ gp = lookglo(leaf2.e_v.e_addr.ea_str);
+ if (gp == (glosym_p) 0)
+ return(undefres);
+ if ((gp->gl_rom[MAXROM]&(1<<node->ex_rnode))==0)
+ return(undefres);
+ result.e_v.e_con = gp->gl_rom[node->ex_rnode];
+ return(result);
+ case EX_LOWW:
+ result.e_v.e_con = saveemp[node->ex_lnode].em_u.em_loper&0xFFFF;
+ return(result);
+ case EX_HIGHW:
+ result.e_v.e_con = saveemp[node->ex_lnode].em_u.em_loper>>16;
+ return(result);
+ case EX_NCPEQ:
+ assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
+ result.e_v.e_con = leaf1.e_v.e_con==leaf2.e_v.e_con;
+ return(result);
+ case EX_SCPEQ:
+ assert(leaf1.e_typ == EV_ADDR && leaf2.e_typ == EV_ADDR);
+ result.e_v.e_con =
+ (strcmp(leaf1.e_v.e_addr.ea_str,leaf2.e_v.e_addr.ea_str)==0 &&
+ leaf1.e_v.e_addr.ea_off==leaf2.e_v.e_addr.ea_off);
+ return(result);
+ case EX_RCPEQ:
+ assert(leaf1.e_typ == EV_REG && leaf2.e_typ == EV_REG);
+ result.e_v.e_con = leaf1.e_v.e_reg==leaf2.e_v.e_reg;
+ return(result);
+ case EX_NCPNE:
+ assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
+ result.e_v.e_con = leaf1.e_v.e_con!=leaf2.e_v.e_con;
+ return(result);
+ case EX_SCPNE:
+ assert(leaf1.e_typ == EV_ADDR && leaf2.e_typ == EV_ADDR);
+ result.e_v.e_con =
+ !(strcmp(leaf1.e_v.e_addr.ea_str,leaf2.e_v.e_addr.ea_str)==0 &&
+ leaf1.e_v.e_addr.ea_off==leaf2.e_v.e_addr.ea_off);
+ return(result);
+ case EX_RCPNE:
+ assert(leaf1.e_typ == EV_REG && leaf2.e_typ == EV_REG);
+ result.e_v.e_con = leaf1.e_v.e_reg!=leaf2.e_v.e_reg;
+ return(result);
+ case EX_NCPGT:
+ assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
+ result.e_v.e_con = leaf1.e_v.e_con>leaf2.e_v.e_con;
+ return(result);
+ case EX_NCPGE:
+ assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
+ result.e_v.e_con = leaf1.e_v.e_con>=leaf2.e_v.e_con;
+ return(result);
+ case EX_NCPLT:
+ assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
+ result.e_v.e_con = leaf1.e_v.e_con<leaf2.e_v.e_con;
+ return(result);
+ case EX_NCPLE:
+ assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
+ result.e_v.e_con = leaf1.e_v.e_con<=leaf2.e_v.e_con;
+ return(result);
+ case EX_OR2:
+ assert(leaf1.e_typ == EV_INT);
+ if (leaf1.e_v.e_con==0)
+ return(compute(&enodes[node->ex_rnode]));
+ return(leaf1);
+ case EX_AND2:
+ assert(leaf1.e_typ == EV_INT);
+ if (leaf1.e_v.e_con!=0)
+ return(compute(&enodes[node->ex_rnode]));
+ return(leaf1);
+ case EX_PLUS:
+ assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
+ result.e_v.e_con=leaf1.e_v.e_con+leaf2.e_v.e_con;
+ return(result);
+ case EX_CAT:
+ assert(leaf1.e_typ == EV_ADDR && leaf2.e_typ == EV_ADDR);
+ result.e_typ = EV_ADDR;
+ result.e_v.e_addr.ea_str = mycat(leaf1.e_v.e_addr.ea_str,leaf2.e_v.e_addr.ea_str);
+ result.e_v.e_addr.ea_off = leaf1.e_v.e_addr.ea_off+leaf2.e_v.e_addr.ea_off;
+ return(result);
+ case EX_MINUS:
+ assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
+ result.e_v.e_con = leaf1.e_v.e_con - leaf2.e_v.e_con;
+ return(result);
+ case EX_TIMES:
+ assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
+ result.e_v.e_con = leaf1.e_v.e_con * leaf2.e_v.e_con;
+ return(result);
+ case EX_DIVIDE:
+ assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
+ result.e_v.e_con = leaf1.e_v.e_con / leaf2.e_v.e_con;
+ return(result);
+ case EX_MOD:
+ assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
+ result.e_v.e_con = leaf1.e_v.e_con % leaf2.e_v.e_con;
+ return(result);
+ case EX_LSHIFT:
+ assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
+ result.e_v.e_con = leaf1.e_v.e_con << leaf2.e_v.e_con;
+ return(result);
+ case EX_RSHIFT:
+ assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
+ result.e_v.e_con = leaf1.e_v.e_con >> leaf2.e_v.e_con;
+ return(result);
+ case EX_NOT:
+ assert(leaf1.e_typ == EV_INT);
+ result.e_v.e_con = !leaf1.e_v.e_con;
+ return(result);
+ case EX_COMP:
+ assert(leaf1.e_typ == EV_INT);
+ result.e_v.e_con = ~leaf1.e_v.e_con;
+ return(result);
+ case EX_STRING:
+ result.e_typ = EV_ADDR;
+ result.e_v.e_addr.ea_str = codestrings[node->ex_lnode];
+ result.e_v.e_addr.ea_off = 0;
+ return(result);
+ case EX_DEFINED:
+ result.e_v.e_con=leaf1.e_typ!=EV_UNDEF;
+ return(result);
+ case EX_SUBREG:
+ result.e_typ = EV_REG;
+ tp= &fakestack[stackheight-node->ex_lnode];
+ assert(tp->t_token == -1);
+ tmpreg= tp->t_att[0].ar;
+#if MAXMEMBERS!=0
+ if (node->ex_rnode)
+ tmpreg=machregs[tmpreg].r_members[node->ex_rnode-1];
+#endif
+ result.e_v.e_reg=tmpreg;
+ return(result);
+ case EX_TOSTRING:
+ assert(leaf1.e_typ == EV_INT);
+ result.e_typ = EV_ADDR;
+ result.e_v.e_addr.ea_str = 0;
+ result.e_v.e_addr.ea_off = leaf1.e_v.e_con;
+ return(result);
+#ifdef REGVARS
+ case EX_INREG:
+ assert(leaf1.e_typ == EV_INT);
+ if ((result.e_v.e_con = isregvar((long) leaf1.e_v.e_con))>0)
+ result.e_v.e_con = machregs[result.e_v.e_con].r_size;
+ return(result);
+ case EX_REGVAR:
+ assert(leaf1.e_typ == EV_INT);
+ i = isregvar((long) leaf1.e_v.e_con);
+ if (i<=0)
+ return(undefres);
+ result.e_typ = EV_REG;
+ result.e_v.e_reg=i;
+ return(result);
+#endif
+ case EX_UMINUS:
+ assert(leaf1.e_typ == EV_INT);
+ result.e_v.e_con = -leaf1.e_v.e_con;
+ return(result);
+ }
+}
--- /dev/null
+/* $Header$ */
+
+typedef struct cost {
+ short ct_space;
+ short ct_time;
+} cost_t,*cost_p;
+
+typedef struct {
+ string ea_str;
+ word ea_off;
+} addr_t;
+
+typedef struct {
+ int t_token; /* kind of token, -1 for register */
+ union {
+ word aw; /* integer type */
+ addr_t aa; /* address type */
+ int ar; /* register type */
+ } t_att[TOKENSIZE];
+} token_t,*token_p;
+
+struct reginfo {
+ int r_repr; /* index in string table */
+ int r_size; /* size in bytes */
+#if MAXMEMBERS!=0
+ int r_members[MAXMEMBERS]; /* register contained within this reg */
+ short r_clash[REGSETSIZE]; /* set of clashing registers */
+#endif
+ int r_refcount; /* Times in use */
+ token_t r_contents; /* Current contents */
+ int r_tcount; /* Temporary count difference */
+};
+
+#if MAXMEMBERS!=0
+#define clash(a,b) ((machregs[a].r_clash[(b)>>4]&(1<<((b)&017)))!=0)
+#else
+#define clash(a,b) ((a)==(b))
+#endif
+
+typedef struct {
+ int t_size; /* size in bytes */
+ cost_t t_cost; /* cost in bytes and time */
+ byte t_type[TOKENSIZE]; /* types of attributes, TT_??? */
+ int t_format; /* index of formatstring */
+} tkdef_t,*tkdef_p;
+
+struct emline {
+ int em_instr;
+ int em_optyp;
+ string em_soper;
+ union {
+ word em_ioper;
+ long em_loper;
+ } em_u;
+};
+
+#define OPNO 0
+#define OPINT 1
+#define OPSYMBOL 2
+
+typedef struct {
+ int rl_n; /* number in list */
+ int rl_list[NREGS];
+} rl_t,*rl_p;
--- /dev/null
+#ifndef NORCSID
+static char rcsid[] = "$Header$";
+#endif
+
+#include "assert.h"
+#include "equiv.h"
+#include "param.h"
+#include "tables.h"
+#include "types.h"
+#include <cgg_cg.h>
+#include "data.h"
+#include "result.h"
+#include "extern.h"
+
+/*
+ * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ *
+ * This product is part of the Amsterdam Compiler Kit.
+ *
+ * Permission to use, sell, duplicate or disclose this software must be
+ * obtained in writing. Requests for such permissions may be sent to
+ *
+ * Dr. Andrew S. Tanenbaum
+ * Wiskundig Seminarium
+ * Vrije Universiteit
+ * Postbox 7161
+ * 1007 MC Amsterdam
+ * The Netherlands
+ *
+ * Author: Hans van Staveren
+ */
+
+extern string myalloc();
+
+int rar[MAXCREG];
+rl_p *lar;
+int maxindex;
+int regclass[NREGS];
+struct perm *perms;
+
+struct perm *
+tuples(regls,nregneeded) rl_p *regls; {
+ int class=0;
+ register i,j;
+
+ /*
+ * First compute equivalence classes of registers.
+ */
+
+ for (i=0;i<NREGS;i++) {
+ regclass[i] = class++;
+ if (getrefcount(i) == 0) {
+ for (j=0;j<i;j++) {
+ if (eqregclass(i,j) &&
+ eqtoken(&machregs[i].r_contents,
+ &machregs[j].r_contents)) {
+ regclass[i] = regclass[j];
+ break;
+ }
+ }
+ }
+ }
+
+ /*
+ * Now create tuples through a recursive function
+ */
+
+ maxindex = nregneeded;
+ lar = regls;
+ perms = 0;
+ permute(0);
+ return(perms);
+}
+
+permute(index) {
+ register struct perm *pp;
+ register rl_p rlp;
+ register i,j;
+
+ if (index == maxindex) {
+ for (pp=perms; pp != 0; pp=pp->p_next) {
+ for (i=0; i<maxindex; i++)
+ if (regclass[rar[i]] != regclass[pp->p_rar[i]])
+ goto diff;
+ for (i=0; i<maxindex; i++)
+ for (j=0; j<i; j++)
+ if (clash(rar[i],rar[j]) !=
+ clash(pp->p_rar[i],pp->p_rar[j]))
+ goto diff;
+ return;
+ diff: ;
+ }
+ pp = (struct perm *) myalloc(sizeof ( *pp ));
+ pp->p_next = perms;
+ for (i=0; i<maxindex; i++)
+ pp->p_rar[i] = rar[i];
+ perms = pp;
+ } else {
+ rlp=lar[index];
+ for (i=rlp->rl_n-1; i>=0; i--) {
+ rar[index] = rlp->rl_list[i];
+ permute(index+1);
+ }
+ }
+}
--- /dev/null
+/* $Header$ */
+
+#define MAXCREG 4
+
+struct perm {
+ struct perm *p_next;
+ int p_rar[MAXCREG];
+};
--- /dev/null
+/* $Header$ */
+
+extern int maxply; /* amount of lookahead allowed */
+extern int stackheight; /* # of tokens on fakestack */
+extern token_t fakestack[]; /* fakestack itself */
+extern int nallreg; /* number of allocated registers */
+extern int allreg[]; /* array of allocated registers */
+extern token_p curtoken; /* pointer to current token */
+extern result_t dollar[]; /* Values of $1,$2 etc.. */
+extern int nemlines; /* # of EM instructions in core */
+extern struct emline emlines[]; /* EM instructions itself */
+extern struct emline *emp; /* pointer to current instr */
+extern struct emline *saveemp; /* pointer to start of pattern */
+extern int tokpatlen; /* length of current stackpattern */
+extern rl_p curreglist; /* side effect of findcoerc() */
+#ifndef NDEBUG
+extern int Debug; /* on/off debug printout */
+#endif
+
+/*
+ * Next descriptions are external declarations for tables created
+ * by bootgram.
+ * All definitions are to be found in tables.c (Not for humans)
+ */
+
+extern byte coderules[]; /* pseudo code for cg itself */
+extern char stregclass[]; /* static register class */
+extern struct reginfo machregs[]; /* register info */
+extern tkdef_t tokens[]; /* token info */
+extern node_t enodes[]; /* expression nodes */
+extern string codestrings[]; /* table of strings */
+extern set_t machsets[]; /* token expression table */
+extern inst_t tokeninstances[]; /* token instance description table */
+extern move_t moves[]; /* move descriptors */
+extern test_t tests[]; /* test descriptors */
+extern byte pattern[]; /* EM patterns */
+extern int pathash[256]; /* Indices into previous */
+extern c1_t c1coercs[]; /* coercions type 1 */
+#ifdef MAXSPLIT
+extern c2_t c2coercs[]; /* coercions type 2 */
+#endif MAXSPLIT
+extern c3_t c3coercs[]; /* coercions type 3 */
+extern struct reginfo **reglist[]; /* lists of registers per property */
+
+#define eqregclass(r1,r2) (stregclass[r1]==stregclass[r2])
+
+#ifdef REGVARS
+extern int nregvar[]; /* # of register variables per type */
+extern int *rvnumbers[]; /* lists of numbers */
+#endif
--- /dev/null
+#ifndef NORCSID
+static char rcsid2[] = "$Header$";
+#endif
+
+#include <stdio.h>
+#include "assert.h"
+#include <em_spec.h>
+#include <em_pseu.h>
+#include <em_flag.h>
+#include <em_ptyp.h>
+#include <em_mes.h>
+#include "mach.h"
+#include "param.h"
+#include "tables.h"
+#include "types.h"
+#include <cgg_cg.h>
+#include "data.h"
+#include "result.h"
+#ifdef REGVARS
+#include "regvar.h"
+#include <em_reg.h>
+#endif
+#include "extern.h"
+
+/*
+ * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ *
+ * This product is part of the Amsterdam Compiler Kit.
+ *
+ * Permission to use, sell, duplicate or disclose this software must be
+ * obtained in writing. Requests for such permissions may be sent to
+ *
+ * Dr. Andrew S. Tanenbaum
+ * Wiskundig Seminarium
+ * Vrije Universiteit
+ * Postbox 7161
+ * 1007 MC Amsterdam
+ * The Netherlands
+ *
+ * Author: Hans van Staveren
+ */
+
+#ifndef newplb /* retrofit for older mach.h */
+#define newplb newilb
+#endif
+
+#ifdef fmt_id
+#ifdef id_first
+It is an error to define both fmt_id and id_first.
+Read the documentation.
+#endif
+#endif
+
+#ifdef fmt_ilb
+#ifdef ilb_fmt
+It is an error to define both fmt_ilb and ilb_fmt.
+Read the documentation.
+#endif
+#endif
+
+/* segment types for switchseg() */
+#define SEGTXT 0
+#define SEGCON 1
+#define SEGROM 2
+#define SEGBSS 3
+
+long con();
+
+#define get8() getc(emfile)
+
+#define MAXSTR 256
+
+FILE *emfile;
+extern FILE *codefile;
+
+int nextispseu,savetab1;
+int opcode;
+int offtyp;
+long argval;
+int dlbval;
+char str[MAXSTR],argstr[32],labstr[32];
+int strsiz;
+int holno=0;
+int procno=0;
+int curseg= -1;
+int part_size=0;
+word part_word=0;
+int endofprog=0;
+#ifdef REGVARS
+int regallowed=0;
+#endif
+
+extern char em_flag[];
+extern short em_ptyp[];
+extern long atol();
+extern double atof();
+
+#define sp_cstx sp_cst2
+
+string tostring();
+string holstr();
+string strarg();
+string mystrcpy();
+long get32();
+
+in_init(filename) char *filename; {
+
+ if ((emfile=freopen(filename,"r",stdin))==NULL)
+ error("Can't open %s",filename);
+ if (get16()!=sp_magic)
+ error("Bad format %s",filename);
+}
+
+in_finish() {
+}
+
+fillemlines() {
+ register int t,i;
+ register struct emline *lp;
+
+ while ((emlines+nemlines)-emp<MAXEMLINES-5) {
+ assert(nemlines<MAXEMLINES);
+ if (nextispseu) {
+ emlines[nemlines].em_instr=0;
+ return;
+ }
+ lp = &emlines[nemlines++];
+
+ switch(t=table1()) {
+ default:
+ error("unknown instruction byte");
+ case sp_ilb1:
+ case sp_ilb2:
+ case sp_fpseu:
+ case sp_dlb1:
+ case sp_dlb2:
+ case sp_dnam:
+ nextispseu=1; savetab1=t;
+ nemlines--;
+ lp->em_instr = 0;
+ return;
+ case EOF:
+ nextispseu=1; savetab1=t;
+ endofprog=1;
+ nemlines--;
+ lp->em_instr = 0;
+ return;
+ case sp_fmnem:
+ lp->em_instr = opcode;
+ break;
+ }
+ i=em_flag[lp->em_instr-sp_fmnem] & EM_PAR;
+ if ( i == PAR_NO ) {
+ lp->em_optyp = OPNO;
+ lp->em_soper = 0;
+ continue;
+ }
+ t= em_ptyp[i];
+ t= getarg(t);
+ switch(i) {
+ case PAR_L:
+ assert(t == sp_cstx);
+ if (argval >= 0)
+ argval += TEM_BSIZE;
+ lp->em_optyp = OPINT;
+ lp->em_u.em_ioper = argval;
+ lp->em_soper = tostring((word) argval);
+ continue;
+ case PAR_G:
+ if (t != sp_cstx)
+ break;
+ lp->em_optyp = OPSYMBOL;
+ lp->em_soper = holstr((word) argval);
+ continue;
+ case PAR_B:
+ t = sp_ilb2;
+ break;
+ case PAR_D:
+ assert(t == sp_cstx);
+ lp->em_optyp = OPSYMBOL;
+ lp->em_soper = strarg(t);
+ lp->em_u.em_loper = argval;
+ continue;
+ }
+ lp->em_soper = strarg(t);
+ if (t==sp_cend)
+ lp->em_optyp = OPNO;
+ else if (t==sp_cstx) {
+ lp->em_optyp = OPINT;
+ lp->em_u.em_ioper = argval;
+ } else
+ lp->em_optyp = OPSYMBOL;
+ }
+}
+
+dopseudo() {
+ register b,t;
+ register full n;
+ register long save;
+ word romcont[MAXROM+1];
+ int nromwords;
+ int rombit,rommask;
+ unsigned dummy,stackupto();
+
+ if (nextispseu==0 || nemlines>0)
+ error("No table entry for %d",emlines[0].em_instr);
+ nextispseu=0;
+ switch(savetab1) {
+ case sp_ilb1:
+ case sp_ilb2:
+ swtxt();
+ dummy = stackupto(&fakestack[stackheight-1],maxply,TRUE);
+ cleanregs();
+ strarg(savetab1);
+ newilb(argstr);
+#ifndef NDEBUG
+ { extern int Debug; extern char * strtdebug;
+ if (strcmp(strtdebug,argstr)==0)
+ Debug = strtdebug[-2]-'0';
+ }
+#endif
+ return;
+ case sp_dlb1:
+ case sp_dlb2:
+ case sp_dnam:
+ strarg(savetab1);
+ savelab();
+ return;
+ case sp_fpseu:
+ break;
+ case EOF:
+ swtxt();
+ in_finish();
+ out_finish();
+ popstr(0);
+ tstoutput();
+ exit(0);
+ default:
+ error("Unknown opcode %d",savetab1);
+ }
+ switch (opcode) {
+ case ps_hol:
+ sprintf(labstr,hol_fmt,++holno);
+ case ps_bss:
+ getarg(cst_ptyp);
+ n = (full) argval;
+ t = getarg(val_ptyp);
+ save = argval;
+ getarg(cst_ptyp);
+ b = (int) argval;
+ argval = save;
+ bss(n,t,b);
+ break;
+ case ps_con:
+ switchseg(SEGCON);
+ dumplab();
+ con(getarg(val_ptyp));
+ while ((t = getarg(any_ptyp)) != sp_cend)
+ con(t);
+ break;
+ case ps_rom:
+ switchseg(SEGROM);
+ xdumplab();
+ nromwords=0;
+ rommask=0;
+ rombit=1;
+ t=getarg(val_ptyp);
+ while (t!=sp_cend) {
+ if (t==sp_cstx && nromwords<MAXROM) {
+ romcont[nromwords] = (word) argval;
+ rommask |= rombit;
+ }
+ nromwords++;
+ rombit <<= 1;
+ con(t);
+ t=getarg(any_ptyp);
+ }
+ if (rommask != 0) {
+ romcont[MAXROM]=rommask;
+ enterglo(labstr,romcont);
+ }
+ labstr[0]=0;
+ break;
+ case ps_mes:
+ getarg(ptyp(sp_cst2));
+ if (argval == ms_emx) {
+ getarg(ptyp(sp_cst2));
+ if (argval != TEM_WSIZE)
+ fatal("bad word size");
+ getarg(ptyp(sp_cst2));
+ if (argval != TEM_PSIZE)
+ fatal("bad pointer size");
+ if ( getarg(any_ptyp)!=sp_cend )
+ fatal("too many parameters");
+#ifdef REGVARS
+ } else if (argval == ms_gto) {
+ getarg(ptyp(sp_cend));
+ if (!regallowed)
+ error("mes 3 not allowed here");
+ fixregvars(TRUE);
+ regallowed=0;
+ } else if (argval == ms_reg) {
+ long r_off;
+ int r_size,r_type,r_score;
+ struct regvar *linkreg();
+
+ if (!regallowed)
+ error("mes 3 not allowed here");
+ if(getarg(ptyp(sp_cst2)|ptyp(sp_cend)) == sp_cend) {
+ fixregvars(FALSE);
+ regallowed=0;
+ } else {
+ r_off = argval;
+ if (r_off >= 0)
+ r_off += TEM_BSIZE;
+ getarg(ptyp(sp_cst2));
+ r_size = argval;
+ getarg(ptyp(sp_cst2));
+ r_type = argval;
+ if (r_type<reg_any || r_type>reg_float)
+ fatal("Bad type in register message");
+ if(getarg(ptyp(sp_cst2)|ptyp(sp_cend)) == sp_cend)
+ r_score = 0;
+ else {
+ r_score = argval;
+ if ( getarg(any_ptyp)!=sp_cend )
+ fatal("too many parameters");
+ }
+ tryreg(linkreg(r_off,r_size,r_type,r_score),r_type);
+ }
+#endif
+ } else
+ mes((word)argval);
+ break;
+ case ps_exa:
+ strarg(getarg(sym_ptyp));
+ ex_ap(argstr);
+ break;
+ case ps_ina:
+ strarg(getarg(sym_ptyp));
+ in_ap(argstr);
+ break;
+ case ps_exp:
+ strarg(getarg(ptyp(sp_pnam)));
+ ex_ap(argstr);
+ break;
+ case ps_inp:
+ strarg(getarg(ptyp(sp_pnam)));
+ in_ap(argstr);
+ break;
+ case ps_pro:
+ switchseg(SEGTXT);
+ procno++;
+ strarg(getarg(ptyp(sp_pnam)));
+ newplb(argstr);
+ getarg(cst_ptyp);
+ prolog((full)argval);
+#ifdef REGVARS
+ regallowed++;
+#endif
+ break;
+ case ps_end:
+ getarg(cst_ptyp | ptyp(sp_cend));
+ cleanregs();
+#ifdef REGVARS
+ unlinkregs();
+#endif
+ tstoutput();
+ break;
+ default:
+ error("No table entry for %d",savetab1);
+ }
+}
+
+/* ----- input ----- */
+
+int getarg(typset) {
+ register t,argtyp;
+
+ argtyp = t = table2();
+ if (t == EOF)
+ fatal("unexpected EOF");
+ t -= sp_fspec;
+ t = 1 << t;
+ if ((typset & t) == 0)
+ error("bad argument type %d",argtyp);
+ return(argtyp);
+}
+
+int table1() {
+ register i;
+
+ i = get8();
+ if (i < sp_fmnem+sp_nmnem && i >= sp_fmnem) {
+ opcode = i;
+ return(sp_fmnem);
+ }
+ if (i < sp_fpseu+sp_npseu && i >= sp_fpseu) {
+ opcode = i;
+ return(sp_fpseu);
+ }
+ if (i < sp_filb0+sp_nilb0 && i >= sp_filb0) {
+ argval = i - sp_filb0;
+ return(sp_ilb2);
+ }
+ return(table3(i));
+}
+
+int table2() {
+ register i;
+
+ i = get8();
+ if (i < sp_fcst0+sp_ncst0 && i >= sp_fcst0) {
+ argval = i - sp_zcst0;
+ return(sp_cstx);
+ }
+ return(table3(i));
+}
+
+int table3(i) {
+ word consiz;
+
+ switch(i) {
+ case sp_ilb1:
+ argval = get8();
+ break;
+ case sp_dlb1:
+ dlbval = get8();
+ break;
+ case sp_dlb2:
+ dlbval = get16();
+ break;
+ case sp_cst2:
+ i = sp_cstx;
+ case sp_ilb2:
+ argval = get16();
+ break;
+ case sp_cst4:
+ i = sp_cstx;
+ argval = get32();
+ break;
+ case sp_dnam:
+ case sp_pnam:
+ case sp_scon:
+ getstring();
+ break;
+ case sp_doff:
+ offtyp = getarg(sym_ptyp);
+ getarg(cst_ptyp);
+ break;
+ case sp_icon:
+ case sp_ucon:
+ case sp_fcon:
+ getarg(cst_ptyp);
+ consiz = (word) argval;
+ getstring();
+ argval = consiz;
+ break;
+ }
+ return(i);
+}
+
+int get16() {
+ register int l_byte, h_byte;
+
+ l_byte = get8();
+ h_byte = get8();
+ if ( h_byte>=128 ) h_byte -= 256 ;
+ return l_byte | (h_byte*256) ;
+}
+
+long get32() {
+ register long l;
+ register int h_byte;
+
+ l = get8();
+ l |= ((unsigned) get8())*256 ;
+ l |= get8()*256L*256L ;
+ h_byte = get8() ;
+ if ( h_byte>=128 ) h_byte -= 256 ;
+ return l | (h_byte*256L*256*256L) ;
+}
+
+getstring() {
+ register char *p;
+ register n;
+
+ getarg(cst_ptyp);
+ if (argval < 0 || argval > MAXSTR-1)
+ fatal("string/identifier too long");
+ strsiz = n = (int) argval;
+ p = str;
+ while (--n >= 0)
+ *p++ = get8();
+ *p++ = '\0';
+}
+
+char *strarg(t) {
+ register char *p;
+
+ switch (t) {
+ case sp_ilb1:
+ case sp_ilb2:
+#ifdef fmt_ilb
+ fmt_ilb(procno,((int) argval),argstr);
+#else
+ sprintf(argstr,ilb_fmt,procno,(int)argval);
+#endif
+ break;
+ case sp_dlb1:
+ case sp_dlb2:
+ sprintf(argstr,dlb_fmt,dlbval);
+ break;
+ case sp_cstx:
+ sprintf(argstr,cst_fmt,(full)argval);
+ break;
+ case sp_dnam:
+ case sp_pnam:
+#ifdef fmt_id
+ fmt_id(str,argstr);
+#else
+ p = argstr;
+ if (strsiz < 8 || str[0] == id_first)
+ *p++ = id_first;
+ sprintf(p,"%.*s",strsiz,str);
+#endif
+ break;
+ case sp_doff:
+ strarg(offtyp);
+ for (p = argstr; *p; p++)
+ ;
+ if (argval >= 0)
+ *p++ = '+';
+ sprintf(p,off_fmt,(full)argval);
+ break;
+ case sp_cend:
+ return("");
+ }
+ return(mystrcpy(argstr));
+}
+
+bss(n,t,b) full n; {
+ register long s;
+
+ if (n % TEM_WSIZE)
+ fatal("bad BSS size");
+ if (b==0
+#ifdef BSS_INIT
+ || (t==sp_cstx && argval==BSS_INIT)
+#endif BSS_INIT
+ ) {
+ switchseg(SEGBSS);
+ newlbss(labstr,n);
+ labstr[0]=0;
+ return;
+ }
+ switchseg(SEGCON);
+ dumplab();
+ while (n > 0)
+ n -= (s = con(t));
+ if (s % TEM_WSIZE)
+ fatal("bad BSS initializer");
+}
+
+long con(t) {
+ register i;
+
+ strarg(t);
+ switch (t) {
+ case sp_ilb1:
+ case sp_ilb2:
+ case sp_pnam:
+ part_flush();
+ con_ilb(argstr);
+ return((long)TEM_PSIZE);
+ case sp_dlb1:
+ case sp_dlb2:
+ case sp_dnam:
+ case sp_doff:
+ part_flush();
+ con_dlb(argstr);
+ return((long)TEM_PSIZE);
+ case sp_cstx:
+ con_part(TEM_WSIZE,(word)argval);
+ return((long)TEM_WSIZE);
+ case sp_scon:
+ for (i = 0; i < strsiz; i++)
+ con_part(1,(word) str[i]);
+ return((long)strsiz);
+ case sp_icon:
+ case sp_ucon:
+ if (argval > TEM_WSIZE) {
+ part_flush();
+ con_mult((word)argval);
+ } else {
+ con_part((int)argval,(word)atol(str));
+ }
+ return(argval);
+ case sp_fcon:
+ part_flush();
+ con_float();
+ return(argval);
+ }
+ assert(FALSE);
+ /* NOTREACHED */
+}
+
+extern char *segname[];
+
+swtxt() {
+ switchseg(SEGTXT);
+}
+
+switchseg(s) {
+
+ if (s == curseg)
+ return;
+ part_flush();
+ if ((curseg = s) >= 0)
+ fprintf(codefile,"%s\n",segname[s]);
+}
+
+savelab() {
+ register char *p,*q;
+
+ part_flush();
+ if (labstr[0]) {
+ dlbdlb(argstr,labstr);
+ return;
+ }
+ p = argstr;
+ q = labstr;
+ while (*q++ = *p++)
+ ;
+}
+
+dumplab() {
+
+ if (labstr[0] == 0)
+ return;
+ assert(part_size == 0);
+ newdlb(labstr);
+ labstr[0] = 0;
+}
+
+xdumplab() {
+
+ if (labstr[0] == 0)
+ return;
+ assert(part_size == 0);
+ newdlb(labstr);
+}
+
+part_flush() {
+
+ /*
+ * Each new data fragment and each data label starts at
+ * a new target machine word
+ */
+ if (part_size == 0)
+ return;
+ con_cst(part_word);
+ part_size = 0;
+ part_word = 0;
+}
+
+string holstr(n) word n; {
+
+ sprintf(str,hol_off,n,holno);
+ return(mystrcpy(str));
+}
+
+
+/* ----- machine dependent routines ----- */
+
+#include "mach.c"
--- /dev/null
+#ifndef NORCSID
+static char rcsid[] = "$Header$";
+#endif
+
+#include "assert.h"
+#include <stdio.h>
+#include "param.h"
+#include "tables.h"
+#include "types.h"
+#include <cgg_cg.h>
+#include "data.h"
+#include "result.h"
+#include "extern.h"
+
+/*
+ * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ *
+ * This product is part of the Amsterdam Compiler Kit.
+ *
+ * Permission to use, sell, duplicate or disclose this software must be
+ * obtained in writing. Requests for such permissions may be sent to
+ *
+ * Dr. Andrew S. Tanenbaum
+ * Wiskundig Seminarium
+ * Vrije Universiteit
+ * Postbox 7161
+ * 1007 MC Amsterdam
+ * The Netherlands
+ *
+ * Author: Hans van Staveren
+ */
+
+string mystrcpy();
+
+FILE *codefile;
+
+out_init(filename) char *filename; {
+
+#ifndef NDEBUG
+ static char stderrbuff[BUFSIZ];
+
+ if (Debug) {
+ codefile = stderr;
+ if (!isatty(2))
+ setbuf(stderr,stderrbuff);
+ } else {
+#endif
+ if (filename == (char *) 0)
+ codefile = stdout;
+ else
+ if ((codefile=freopen(filename,"w",stdout))==NULL)
+ error("Can't create %s",filename);
+#ifndef NDEBUG
+ }
+#endif
+}
+
+out_finish() {
+
+#ifndef NDEBUG
+ if (Debug)
+ fflush(stderr);
+ else
+#endif
+ fclose(codefile);
+#ifdef TABLEDEBUG
+ termlset();
+#endif
+}
+
+tstoutput() {
+
+ if (ferror(codefile))
+ error("Write error on output");
+}
+
+genstr(stringno) {
+
+ fputs(codestrings[stringno],codefile);
+}
+
+string ad2str(ad) addr_t ad; {
+ static char buf[100];
+
+ if (ad.ea_str==0)
+ ad.ea_str="";
+ sprintf(buf,"%s%c%ld",ad.ea_str,ad.ea_off>=0 ? '+' : ' ',(long)ad.ea_off);
+ return(mystrcpy(buf));
+}
+
+praddr(ad) addr_t ad; {
+
+ if (ad.ea_str==0)
+ fprintf(codefile,WRD_FMT,ad.ea_off);
+ else {
+ fprintf(codefile,"%s",ad.ea_str);
+ if (ad.ea_off<0)
+ fprintf(codefile,WRD_FMT,ad.ea_off);
+ else if(ad.ea_off>0) {
+ fputc('+',codefile);
+ fprintf(codefile,WRD_FMT,ad.ea_off);
+ }
+ }
+}
+
+gennl() {
+ fputc('\n',codefile);
+}
+
+prtoken(tp,leadingchar) token_p tp; {
+ register c;
+ register char *code;
+ register tkdef_p tdp;
+
+ fputc(leadingchar,codefile);
+ if (tp->t_token == -1) {
+ fprintf(codefile,"%s",codestrings[machregs[tp->t_att[0].ar].r_repr]);
+ return;
+ }
+ tdp = &tokens[tp->t_token];
+ assert(tdp->t_format != -1);
+ code = codestrings[tdp->t_format];
+ while ((c = *code++) != 0) {
+ if (c>=' ' && c<='~')
+ fputc(c,codefile);
+ else {
+ assert(c>0 && c<=TOKENSIZE);
+ switch(tdp->t_type[c-1]) {
+ default:
+ assert(FALSE);
+ case EV_INT:
+ fprintf(codefile,WRD_FMT,tp->t_att[c-1].aw);
+ break;
+ case EV_ADDR:
+ praddr(tp->t_att[c-1].aa);
+ break;
+ case EV_REG:
+ fprintf(codefile,"%s",codestrings[machregs[tp->t_att[c-1].ar].r_repr]);
+ break;
+ }
+ }
+ }
+}
--- /dev/null
+#ifndef NORCSID
+static char rcsid[] = "$Header$";
+#endif
+
+#include "param.h"
+#include "tables.h"
+#include "types.h"
+#include "glosym.h"
+
+/*
+ * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ *
+ * This product is part of the Amsterdam Compiler Kit.
+ *
+ * Permission to use, sell, duplicate or disclose this software must be
+ * obtained in writing. Requests for such permissions may be sent to
+ *
+ * Dr. Andrew S. Tanenbaum
+ * Wiskundig Seminarium
+ * Vrije Universiteit
+ * Postbox 7161
+ * 1007 MC Amsterdam
+ * The Netherlands
+ *
+ * Author: Hans van Staveren
+ */
+
+extern string myalloc();
+
+glosym_p glolist= (glosym_p) 0;
+
+enterglo(name,romp) string name; word *romp; {
+ register glosym_p gp;
+ register i;
+
+ gp = (glosym_p) myalloc(sizeof *gp);
+ gp->gl_next = glolist;
+ gp->gl_name = (string) myalloc(strlen(name)+1);
+ strcpy(gp->gl_name,name);
+ for (i=0;i<=MAXROM;i++)
+ gp->gl_rom[i] = romp[i];
+ glolist = gp;
+}
+
+glosym_p lookglo(name) string name; {
+ register glosym_p gp;
+
+ for (gp=glolist;gp != (glosym_p) 0; gp=gp->gl_next)
+ if (strcmp(gp->gl_name,name)==0)
+ return(gp);
+ return((glosym_p) 0);
+}
--- /dev/null
+/* $Header$ */
+
+typedef struct glosym {
+ struct glosym *gl_next;
+ string gl_name;
+ word gl_rom[MAXROM+1];
+} glosym_t,*glosym_p;
+
+glosym_p lookglo();
--- /dev/null
+#ifndef NORCSID
+static char rcsid[] = "$Header$";
+#endif
+
+#include "param.h"
+#include "tables.h"
+
+/*
+ * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ *
+ * This product is part of the Amsterdam Compiler Kit.
+ *
+ * Permission to use, sell, duplicate or disclose this software must be
+ * obtained in writing. Requests for such permissions may be sent to
+ *
+ * Dr. Andrew S. Tanenbaum
+ * Wiskundig Seminarium
+ * Vrije Universiteit
+ * Postbox 7161
+ * 1007 MC Amsterdam
+ * The Netherlands
+ *
+ * Author: Hans van Staveren
+ */
+
+char *progname;
+extern char startupcode[];
+int maxply=1;
+#ifndef NDEBUG
+int Debug=0;
+char *strtdebug="";
+#endif
+
+extern int endofprog;
+
+main(argc,argv) char **argv; {
+ register unsigned n;
+ extern unsigned cc1,cc2,cc3,cc4;
+ unsigned ggd();
+
+ progname = argv[0];
+ while (--argc && **++argv == '-') {
+ switch(argv[0][1]) {
+#ifndef NDEBUG
+ case 'd':
+ if ((Debug = argv[0][2]) != 0) {
+ Debug -= '0';
+ if (argv[0][3] == '@') {
+ Debug = 0;
+ strtdebug = &argv[0][4];
+ }
+ } else
+ Debug++;
+ break;
+#endif
+#ifdef TABLEDEBUG
+ case 'u':
+ case 'U':
+ initlset(argv[0]+1);
+ break;
+#endif
+ case 'p':
+ maxply = atoi(argv[0]+2);
+ break;
+ case 'w': /* weight percentage for size */
+ n=atoi(argv[0]+2);
+ cc1 *= n;
+ cc2 *= 50;
+ cc3 *= (100-n);
+ cc4 *= 50;
+ n=ggd(cc1,cc2);
+ cc1 /= n;
+ cc2 /= n;
+ n=ggd(cc3,cc4);
+ cc3 /= n;
+ cc4 /= n;
+ break;
+ default:
+ error("Unknown flag %c",argv[0][1]);
+ }
+ }
+ if (argc < 1 || argc > 2)
+ error("Usage: %s EMfile [ asfile ]",progname);
+ in_init(argv[0]);
+ out_init(argv[1]);
+ readcodebytes();
+ itokcost();
+ codegen(startupcode,maxply,TRUE,MAXINT,0);
+ error("Bombed out of codegen");
+}
+
+unsigned ggd(a,b) register unsigned a,b; {
+ register unsigned c;
+
+ do {
+ c = a%b; a=b; b=c;
+ } while (c!=0);
+ return(a);
+}
--- /dev/null
+#ifndef NORCSID
+static char rcsid[] = "$Header$";
+#endif
+
+#include "assert.h"
+#include "param.h"
+#include "tables.h"
+#include "types.h"
+#include <cgg_cg.h>
+#include "data.h"
+#include "result.h"
+#include "extern.h"
+
+/*
+ * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ *
+ * This product is part of the Amsterdam Compiler Kit.
+ *
+ * Permission to use, sell, duplicate or disclose this software must be
+ * obtained in writing. Requests for such permissions may be sent to
+ *
+ * Dr. Andrew S. Tanenbaum
+ * Wiskundig Seminarium
+ * Vrije Universiteit
+ * Postbox 7161
+ * 1007 MC Amsterdam
+ * The Netherlands
+ *
+ * Author: Hans van Staveren
+ */
+
+unsigned costcalc();
+
+move(tp1,tp2,ply,toplevel,maxcost) token_p tp1,tp2; unsigned maxcost; {
+ register move_p mp;
+ register unsigned t;
+ register struct reginfo *rp;
+ tkdef_p tdp;
+ int i;
+ unsigned codegen();
+
+ if (eqtoken(tp1,tp2))
+ return(0);
+ if (tp2->t_token == -1) {
+ if (tp1->t_token == -1) {
+ if (eqtoken(&machregs[tp1->t_att[0].ar].r_contents,
+ &machregs[tp2->t_att[0].ar].r_contents) &&
+ machregs[tp1->t_att[0].ar].r_contents.t_token!=0)
+ return(0);
+ erasereg(tp2->t_att[0].ar);
+ machregs[tp2->t_att[0].ar].r_contents =
+ machregs[tp1->t_att[0].ar].r_contents ;
+
+ } else {
+ if (eqtoken(&machregs[tp2->t_att[0].ar].r_contents,tp1))
+ return(0);
+ erasereg(tp2->t_att[0].ar);
+ machregs[tp2->t_att[0].ar].r_contents = *tp1;
+ }
+ for (rp=machregs+1;rp<machregs+NREGS;rp++) {
+ if (rp->r_contents.t_token == 0)
+ continue;
+ assert(rp->r_contents.t_token > 0);
+ tdp = &tokens[rp->r_contents.t_token];
+ for (i=0;i<TOKENSIZE;i++)
+ if (tdp->t_type[i] == EV_REG &&
+ clash(rp->r_contents.t_att[i].ar,tp2->t_att[0].ar)) {
+ erasereg(rp-machregs);
+ break;
+ }
+ }
+ } else if (tp1->t_token == -1) {
+ if (eqtoken(tp2,&machregs[tp1->t_att[0].ar].r_contents))
+ return(0);
+ machregs[tp1->t_att[0].ar].r_contents = *tp2;
+ }
+ /*
+ * If we arrive here the move must really be executed
+ */
+ for (mp=moves;mp->m_set1>=0;mp++) {
+ if (!match(tp1,&machsets[mp->m_set1],mp->m_expr1))
+ continue;
+ if (match(tp2,&machsets[mp->m_set2],mp->m_expr2))
+ break;
+ /*
+ * Correct move rule is found
+ */
+ }
+ assert(mp->m_set1>=0);
+ /*
+ * To get correct interpretation of things like %[1]
+ * in move code we stack tp2 and tp1. This little trick
+ * saves a lot of testing in other places.
+ */
+
+ fakestack[stackheight] = *tp2;
+ fakestack[stackheight+1] = *tp1;
+ stackheight += 2;
+ t = codegen(&coderules[mp->m_cindex],ply,toplevel,maxcost,0);
+ stackheight -= 2;
+ return(t);
+}
+
+#define cocoreg machregs[0].r_contents
+
+setcc(tp) token_p tp; {
+
+ cocoreg = *tp;
+}
+
+test(tp,ply,toplevel,maxcost) token_p tp; unsigned maxcost; {
+ register test_p mp;
+ register unsigned t;
+ register struct reginfo *rp;
+ tkdef_p tdp;
+ int i;
+ unsigned codegen();
+
+ if (cocoreg.t_token!=0) {
+ if (eqtoken(tp,&cocoreg))
+ return(0);
+ if (tp->t_token == -1) {
+ if (eqtoken(&machregs[tp->t_att[0].ar].r_contents,&cocoreg))
+ return(0);
+ }
+ }
+ /*
+ * If we arrive here the test must really be executed
+ */
+ for (mp=tests;mp->t_set>=0;mp++) {
+ if (match(tp,&machsets[mp->t_set],mp->t_expr))
+ break;
+ /*
+ * Correct move rule is found
+ */
+ }
+ assert(mp->t_set>=0);
+ /*
+ * To get correct interpretation of things like %[1]
+ * in test code we stack tp. This little trick
+ * saves a lot of testing in other places.
+ */
+
+ fakestack[stackheight] = *tp;
+ stackheight++;
+ t = codegen(&coderules[mp->t_cindex],ply,toplevel,maxcost,0);
+ stackheight--;
+ return(t);
+}
--- /dev/null
+#ifndef NORCSID
+static char rcsid[] = "$Header$";
+#endif
+
+#include <em_spec.h>
+#include <em_flag.h>
+#include "assert.h"
+#include "param.h"
+#include "tables.h"
+#include "types.h"
+#include <cgg_cg.h>
+#include "data.h"
+#include "result.h"
+#include "extern.h"
+
+/*
+ * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ *
+ * This product is part of the Amsterdam Compiler Kit.
+ *
+ * Permission to use, sell, duplicate or disclose this software must be
+ * obtained in writing. Requests for such permissions may be sent to
+ *
+ * Dr. Andrew S. Tanenbaum
+ * Wiskundig Seminarium
+ * Vrije Universiteit
+ * Postbox 7161
+ * 1007 MC Amsterdam
+ * The Netherlands
+ *
+ * Author: Hans van Staveren
+ */
+
+#ifndef NDEBUG
+#include <stdio.h>
+extern char em_mnem[][4];
+#endif
+
+byte *trypat(bp,len) register byte *bp; {
+ register patlen,i;
+ result_t result;
+
+ getint(patlen,bp);
+ if (len == 3) {
+ if (patlen < 3)
+ return(0);
+ } else {
+ if (patlen != len)
+ return(0);
+ }
+ for(i=0;i<patlen;i++)
+ if (emp[i].em_instr != (*bp++&BMASK))
+ return(0);
+ for (i=0;i<patlen;i++)
+ if (emp[i].em_optyp==OPNO)
+ dollar[i].e_typ=EV_UNDEF;
+ else if ((dollar[i].e_typ=argtyp(emp[i].em_instr))==EV_INT)
+ dollar[i].e_v.e_con=emp[i].em_u.em_ioper;
+ else {
+ dollar[i].e_v.e_addr.ea_str=emp[i].em_soper;
+ dollar[i].e_v.e_addr.ea_off=0;
+ }
+ getint(i,bp);
+ if (i!=0) {
+ result = compute(&enodes[i]);
+ if (result.e_typ != EV_INT || result.e_v.e_con == 0)
+ return(0);
+ }
+#ifndef NDEBUG
+ if (Debug) {
+ fprintf(stderr,"Matched:");
+ for (i=0;i<patlen;i++)
+ fprintf(stderr," %3.3s",em_mnem[emp[i].em_instr-sp_fmnem]);
+ fprintf(stderr,"\n");
+ }
+#endif
+ saveemp = emp;
+ emp += patlen;
+ return(bp);
+}
+
+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(EV_INT);
+ default:
+ return(EV_ADDR);
+ }
+}
+
+byte *nextem(toplevel) {
+ register i;
+ short hash[3];
+ register byte *bp;
+ byte *cp;
+ int index;
+ register struct emline *ep;
+
+ if (toplevel) {
+ if (nemlines && emp>emlines) {
+ nemlines -= emp-emlines;
+ for (i=0,ep=emlines;i<nemlines;i++)
+ *ep++ = *emp++;
+ emp=emlines;
+ }
+ fillemlines();
+ }
+ hash[0] = emp[0].em_instr;
+ hash[1] = (hash[0]<<4) ^ emp[1].em_instr;
+ hash[2] = (hash[1]<<4) ^ emp[2].em_instr;
+ for (i=2;i>=0;i--) {
+ index = pathash[hash[i]&BMASK];
+ while (index != 0) {
+ bp = &pattern[index];
+ if ( bp[PO_HASH] == (hash[i]>>8))
+ if ((cp=trypat(&bp[PO_MATCH],i+1)) != 0)
+ return(cp);
+ index = (bp[PO_NEXT]&BMASK) | (bp[PO_NEXT+1]<<8);
+ }
+ }
+ return(0);
+}
--- /dev/null
+/* $Header$ */
+
+#define BMASK 0377
+#define BSHIFT 8
+
+#define TRUE 1
+#define FALSE 0
+
+#define MAXINT 32767
+#define INFINITY (MAXINT+100)
+
+#define MAXROM 3
+
+/*
+ * Tunable constants
+ */
+
+#define MAXEMLINES 20
+#define MAXFSTACK 20
+#define MAXTDBUG 32
--- /dev/null
+#ifndef NORCSID
+static char rcsid[] = "$Header$";
+#endif
+
+#include "assert.h"
+#include "param.h"
+#include "tables.h"
+#include "types.h"
+#include <cgg_cg.h>
+#include "data.h"
+#include "result.h"
+#include "extern.h"
+
+/*
+ * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ *
+ * This product is part of the Amsterdam Compiler Kit.
+ *
+ * Permission to use, sell, duplicate or disclose this software must be
+ * obtained in writing. Requests for such permissions may be sent to
+ *
+ * Dr. Andrew S. Tanenbaum
+ * Wiskundig Seminarium
+ * Vrije Universiteit
+ * Postbox 7161
+ * 1007 MC Amsterdam
+ * The Netherlands
+ *
+ * Author: Hans van Staveren
+ */
+
+chrefcount(regno,amount,tflag) {
+ register struct reginfo *rp;
+ register i;
+
+ rp= &machregs[regno];
+#if MAXMEMBERS!=0
+ if (rp->r_members[0]==0) {
+#endif
+ rp->r_refcount += amount;
+ if (tflag)
+ rp->r_tcount += amount;
+ assert(rp->r_refcount >= 0);
+#if MAXMEMBERS!=0
+ } else
+ for (i=0;i<MAXMEMBERS;i++)
+ if (rp->r_members[i]!=0)
+ chrefcount(rp->r_members[i],amount,tflag);
+#endif
+}
+
+getrefcount(regno) {
+ register struct reginfo *rp;
+ register i,maxcount;
+
+ rp= &machregs[regno];
+#if MAXMEMBERS!=0
+ if (rp->r_members[0]==0)
+#endif
+ return(rp->r_refcount);
+#if MAXMEMBERS!=0
+ else {
+ maxcount=0;
+ for (i=0;i<MAXMEMBERS;i++)
+ if (rp->r_members[i]!=0)
+ maxcount=max(maxcount,getrefcount(rp->r_members[i]));
+ return(maxcount);
+ }
+#endif
+}
+
+erasereg(regno) {
+ register struct reginfo *rp;
+
+#if MAXMEMBERS==0
+ awayreg(regno);
+#else
+ for (rp=machregs+1;rp<machregs+NREGS;rp++)
+ if (rp->r_clash[regno>>4]&(1<<(regno&017)))
+ awayreg(rp-machregs);
+#endif
+}
+
+awayreg(regno) {
+ register struct reginfo *rp;
+ register tkdef_p tdp;
+ register i;
+
+ rp = &machregs[regno];
+ rp->r_contents.t_token = 0;
+ for (i=0;i<TOKENSIZE;i++)
+ rp->r_contents.t_att[i].aw = 0;
+
+ /* Now erase recursively all registers containing
+ * something using this one
+ */
+ for (rp=machregs;rp<machregs+NREGS;rp++) {
+ if (rp->r_contents.t_token == -1) {
+ if (rp->r_contents.t_att[0].ar == regno)
+ erasereg(rp-machregs);
+ } else {
+ tdp= & tokens[rp->r_contents.t_token];
+ for (i=0;i<TOKENSIZE;i++)
+ if (tdp->t_type[i] == EV_REG &&
+ rp->r_contents.t_att[i].ar == regno) {
+ erasereg(rp-machregs);
+ break;
+ }
+ }
+ }
+}
+
+cleanregs() {
+ register struct reginfo *rp;
+ register i;
+
+ for (rp=machregs;rp<machregs+NREGS;rp++) {
+ rp->r_contents.t_token = 0;
+ for (i=0;i<TOKENSIZE;i++)
+ rp->r_contents.t_att[i].aw = 0;
+ }
+}
+
+#ifndef NDEBUG
+inctcount(regno) {
+ register struct reginfo *rp;
+ register i;
+
+ rp = &machregs[regno];
+#if MAXMEMBERS!=0
+ if (rp->r_members[0] == 0) {
+#endif
+ rp->r_tcount++;
+#if MAXMEMBERS!=0
+ } else {
+ for (i=0;i<MAXMEMBERS;i++)
+ if (rp->r_members[i] != 0)
+ inctcount(rp->r_members[i]);
+ }
+#endif
+}
+
+chkregs() {
+ register struct reginfo *rp;
+ register token_p tp;
+ register tkdef_p tdp;
+ int i;
+
+ for (rp=machregs+1;rp<machregs+NREGS;rp++) {
+ assert(rp->r_tcount==0);
+ }
+ for (tp=fakestack;tp<fakestack+stackheight;tp++) {
+ if (tp->t_token == -1)
+ inctcount(tp->t_att[0].ar);
+ else {
+ tdp = &tokens[tp->t_token];
+ for (i=0;i<TOKENSIZE;i++)
+ if (tdp->t_type[i]==EV_REG)
+ inctcount(tp->t_att[i].ar);
+ }
+ }
+#ifdef REGVARS
+#include <em_reg.h>
+ for(i=reg_any;i<=reg_float;i++) {
+ int j;
+ for(j=0;j<nregvar[i];j++)
+ inctcount(rvnumbers[i][j]);
+ }
+#endif REGVARS
+ for (rp=machregs+1;rp<machregs+NREGS;rp++) {
+ assert(rp->r_refcount==rp->r_tcount);
+ rp->r_tcount=0;
+ }
+}
+#endif
--- /dev/null
+#include "assert.h"
+#include "param.h"
+#include "tables.h"
+
+#ifdef REGVARS
+
+#ifndef NORCSID
+static char rcsid[] = "$Header$";
+#endif
+
+#include "types.h"
+#include <cgg_cg.h>
+#include "data.h"
+#include "regvar.h"
+#include <em_reg.h>
+#include "result.h"
+#include "extern.h"
+
+/*
+ * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ *
+ * This product is part of the Amsterdam Compiler Kit.
+ *
+ * Permission to use, sell, duplicate or disclose this software must be
+ * obtained in writing. Requests for such permissions may be sent to
+ *
+ * Dr. Andrew S. Tanenbaum
+ * Wiskundig Seminarium
+ * Vrije Universiteit
+ * Postbox 7161
+ * 1007 MC Amsterdam
+ * The Netherlands
+ *
+ * Author: Hans van Staveren
+ */
+extern string myalloc();
+struct regvar *rvlist;
+
+struct regvar *
+linkreg(of,sz,tp,sc) long of; {
+ register struct regvar *rvlp;
+
+ rvlp= (struct regvar *) myalloc(sizeof *rvlp);
+ rvlp->rv_next = rvlist;
+ rvlist=rvlp;
+ rvlp->rv_off = of;
+ rvlp->rv_size = sz;
+ rvlp->rv_type = tp;
+ rvlp->rv_score = sc;
+ rvlp->rv_reg = 0; /* no register assigned yet */
+ return(rvlp);
+}
+
+tryreg(rvlp,typ) register struct regvar *rvlp; {
+ int score;
+ register i;
+ register struct regassigned *ra;
+ struct regvar *save;
+
+ if (typ != reg_any && nregvar[typ]!=0) {
+ if (machregs[rvnumbers[typ][0]].r_size!=rvlp->rv_size)
+ score = -1;
+ else
+ score = regscore(rvlp->rv_off,
+ rvlp->rv_size,
+ rvlp->rv_type,
+ rvlp->rv_score,
+ typ); /* machine dependent */
+ ra = regassigned[typ];
+ if (score>ra[nregvar[typ]-1].ra_score) {
+ save = ra[nregvar[typ]-1].ra_rv;
+ for (i=nregvar[typ]-1;i>0 && ra[i-1].ra_score<score;i--)
+ ra[i] = ra[i-1];
+ ra[i].ra_rv = rvlp;
+ ra[i].ra_score = score;
+ if((rvlp=save)==0)
+ return;
+ }
+ }
+ if (nregvar[reg_any]==0)
+ return;
+ if (machregs[rvnumbers[reg_any][0]].r_size!=rvlp->rv_size)
+ score = -1;
+ else
+ score = regscore(rvlp->rv_off,
+ rvlp->rv_size,
+ rvlp->rv_type,
+ rvlp->rv_score,
+ reg_any); /* machine dependent */
+ ra = regassigned[reg_any];
+ if (score>ra[nregvar[reg_any]-1].ra_score) {
+ for (i=nregvar[reg_any]-1;i>0 && ra[i-1].ra_score<score;i--)
+ ra[i] = ra[i-1];
+ ra[i].ra_rv = rvlp;
+ ra[i].ra_score = score;
+ }
+}
+
+fixregvars(saveall) {
+ register struct regvar *rv;
+ register rvtyp,i;
+
+ swtxt();
+ i_regsave(); /* machine dependent initialization */
+ for (rvtyp=reg_any;rvtyp<=reg_float;rvtyp++) {
+ for(i=0;i<nregvar[rvtyp];i++)
+ if (saveall) {
+ struct reginfo *rp;
+ rp= &machregs[rvnumbers[rvtyp][i]];
+ regsave(codestrings[rp->r_repr],(long)-TEM_WSIZE,rp->r_size);
+ } else if(regassigned[rvtyp][i].ra_score>0) {
+ rv=regassigned[rvtyp][i].ra_rv;
+ rv->rv_reg=rvnumbers[rvtyp][i];
+ regsave(codestrings[machregs[rv->rv_reg].r_repr],
+ rv->rv_off,rv->rv_size);
+ }
+ }
+ f_regsave();
+}
+
+isregvar(off) long off; {
+ register struct regvar *rvlp;
+
+ for(rvlp=rvlist;rvlp!=0;rvlp=rvlp->rv_next)
+ if(rvlp->rv_off == off)
+ return(rvlp->rv_reg);
+ return(-1);
+}
+
+unlinkregs() {
+ register struct regvar *rvlp,*t;
+ register struct regassigned *ra;
+ int rvtyp,i;
+
+ for(rvlp=rvlist;rvlp!=0;rvlp=t) {
+ t=rvlp->rv_next;
+ myfree(rvlp);
+ }
+ rvlist=0;
+ for (rvtyp=reg_any;rvtyp<=reg_float;rvtyp++) {
+ for(i=0;i<nregvar[rvtyp];i++) {
+ ra= ®assigned[rvtyp][i];
+ ra->ra_rv = 0;
+ ra->ra_score = 0;
+ }
+ }
+}
+
+#endif REGVARS
+
+/* nothing after this */
--- /dev/null
+/* $Header$ */
+
+struct regvar {
+ struct regvar *rv_next;
+ long rv_off;
+ int rv_size;
+ int rv_type;
+ int rv_score;
+ int rv_reg;
+};
+
+struct regassigned {
+ struct regvar *ra_rv;
+ int ra_score;
+};
+
+extern struct regvar *rvlist;
+extern int nregvar[];
+extern struct regassigned *regassigned[];
--- /dev/null
+/* $Header$ */
+
+struct result {
+ int e_typ; /* EV_INT,EV_REG,EV_STR */
+ union {
+ word e_con;
+ int e_reg;
+ addr_t e_addr;
+ } e_v; /* value */
+};
+
+#define EV_UNDEF 0
+#define EV_INT 1
+#define EV_REG 2
+#define EV_ADDR 3
+
+typedef struct result result_t;
+
+extern result_t compute();
--- /dev/null
+#ifndef NORCSID
+static char rcsid[] = "$Header$";
+#endif
+
+#include "assert.h"
+#include "param.h"
+#include "tables.h"
+#include "types.h"
+#include <cgg_cg.h>
+#include "data.h"
+#include "result.h"
+#include "extern.h"
+
+/*
+ * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ *
+ * This product is part of the Amsterdam Compiler Kit.
+ *
+ * Permission to use, sell, duplicate or disclose this software must be
+ * obtained in writing. Requests for such permissions may be sent to
+ *
+ * Dr. Andrew S. Tanenbaum
+ * Wiskundig Seminarium
+ * Vrije Universiteit
+ * Postbox 7161
+ * 1007 MC Amsterdam
+ * The Netherlands
+ *
+ * Author: Hans van Staveren
+ */
+
+/*
+ * Package for string allocation and garbage collection.
+ * Call salloc(size) to get room for string.
+ * Every now and then call garbage_collect() from toplevel.
+ */
+
+#define MAXSTAB 500
+#define THRESHOLD 200
+
+char *stab[MAXSTAB];
+int nstab=0;
+string malloc();
+
+string myalloc(size) {
+ register string p;
+
+ p = (string) malloc(size);
+ if (p==0)
+ fatal("Out of memory");
+ return(p);
+}
+
+myfree(p) string p; {
+
+ free(p);
+}
+
+popstr(nnstab) {
+ register i;
+
+ for (i=nnstab;i<nstab;i++)
+ myfree(stab[i]);
+ nstab = nnstab;
+}
+
+char *salloc(size) {
+ register char *p;
+
+ if (nstab==MAXSTAB)
+ fatal("String table overflow");
+ p = myalloc(size+1); /* extra room for terminating zero */
+ stab[nstab++] = p;
+ return(p);
+}
+
+compar(p1,p2) char **p1,**p2; {
+
+ assert(*p1 != *p2);
+ if (*p1 < *p2)
+ return(-1);
+ return(1);
+}
+
+garbage_collect() {
+ register i;
+ struct emline *emlp;
+ token_p tp;
+ tkdef_p tdp;
+ struct reginfo *rp;
+ register char **fillp,**scanp;
+ char used[MAXSTAB]; /* could be bitarray */
+
+ if (nstab<THRESHOLD)
+ return;
+ qsort(stab,nstab,sizeof (char *),compar);
+ for (i=0;i<nstab;i++)
+ used[i]= FALSE;
+ for(emlp=emlines;emlp<emlines+nemlines;emlp++)
+ chkstr(emlp->em_soper,used);
+ for (tp= fakestack;tp<&fakestack[stackheight];tp++) {
+ if (tp->t_token== -1)
+ continue;
+ tdp = &tokens[tp->t_token];
+ for (i=0;i<TOKENSIZE;i++)
+ if (tdp->t_type[i] == EV_ADDR)
+ chkstr(tp->t_att[i].aa.ea_str,used);
+ }
+ for (rp= machregs+1; rp<machregs+NREGS; rp++) {
+ tp = &rp->r_contents;
+ assert(tp->t_token != -1);
+ tdp= &tokens[tp->t_token];
+ for (i=0;i<TOKENSIZE;i++)
+ if (tdp->t_type[i] == EV_ADDR)
+ chkstr(tp->t_att[i].aa.ea_str,used);
+ }
+ for (i=0;i<nstab;i++)
+ if (!used[i]) {
+ myfree(stab[i]);
+ stab[i]=0;
+ }
+ fillp=stab;
+ for (scanp=stab;scanp<stab+nstab;scanp++)
+ if (*scanp != 0)
+ *fillp++ = *scanp;
+ nstab = fillp-stab;
+}
+
+chkstr(str,used) string str; char used[]; {
+ register low,middle,high;
+
+ low=0; high=nstab-1;
+ while (high>low) {
+ middle= (low+high)>>1;
+ if (str==stab[middle]) {
+ used[middle]=1;
+ return;
+ }
+ if (str<stab[middle])
+ high = middle-1;
+ else
+ low = middle+1;
+ }
+ if (low==high) {
+ if (str==stab[low]) {
+ used[low]=1;
+ }
+ return;
+ }
+}
--- /dev/null
+#ifndef NORCSID
+static char rcsid[] = "$Header$";
+#endif
+
+#include "assert.h"
+#include "param.h"
+#include "tables.h"
+#include "types.h"
+#include <cgg_cg.h>
+#include "data.h"
+#include "result.h"
+#include "state.h"
+#include "extern.h"
+
+/*
+ * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ *
+ * This product is part of the Amsterdam Compiler Kit.
+ *
+ * Permission to use, sell, duplicate or disclose this software must be
+ * obtained in writing. Requests for such permissions may be sent to
+ *
+ * Dr. Andrew S. Tanenbaum
+ * Wiskundig Seminarium
+ * Vrije Universiteit
+ * Postbox 7161
+ * 1007 MC Amsterdam
+ * The Netherlands
+ *
+ * Author: Hans van Staveren
+ */
+
+extern int nstab; /* salloc.c */
+
+savestatus(sp) register state_p sp; {
+
+ sp->st_sh = stackheight;
+ bmove((short *)fakestack,(short *)sp->st_fs,stackheight*sizeof(token_t));
+ sp->st_na = nallreg;
+ bmove((short *)allreg,(short *)sp->st_ar,nallreg*sizeof(int));
+ sp->st_ct = curtoken;
+ bmove((short *)dollar,(short *)sp->st_do,LONGESTPATTERN*sizeof(result_t));
+ bmove((short *)machregs,(short *)sp->st_mr,NREGS*sizeof(struct reginfo));
+ sp->st_ne = nemlines;
+ bmove((short *)emlines,(short *)sp->st_el,nemlines*sizeof(struct emline));
+ sp->st_em = emp;
+ sp->st_se = saveemp;
+ sp->st_tl = tokpatlen;
+ sp->st_ns = nstab;
+}
+
+restorestatus(sp) register state_p sp; {
+
+ stackheight = sp->st_sh;
+ bmove((short *)sp->st_fs,(short *)fakestack,stackheight*sizeof(token_t));
+ nallreg = sp->st_na;
+ bmove((short *)sp->st_ar,(short *)allreg,nallreg*sizeof(int));
+ curtoken = sp->st_ct;
+ bmove((short *)sp->st_do,(short *)dollar,LONGESTPATTERN*sizeof(result_t));
+ bmove((short *)sp->st_mr,(short *)machregs,NREGS*sizeof(struct reginfo));
+ nemlines = sp->st_ne;
+ bmove((short *)sp->st_el,(short *)emlines,nemlines*sizeof(struct emline));
+ emp = sp->st_em;
+ saveemp = sp->st_se;
+ tokpatlen = sp->st_tl;
+ popstr(sp->st_ns);
+}
+
+bmove(from,to,nbytes) register short *from,*to; register nbytes; {
+
+ if (nbytes<=0)
+ return;
+ assert(sizeof(short)==2 && (nbytes&1)==0);
+ nbytes>>=1;
+ do
+ *to++ = *from++;
+ while (--nbytes);
+}
--- /dev/null
+/* $Header$ */
+
+typedef struct state {
+ struct state *st_next; /* for linked list */
+ int st_sh; /* stackheight */
+ token_t st_fs[MAXFSTACK]; /* fakestack */
+ int st_na; /* nallreg */
+ int st_ar[MAXALLREG]; /* allreg[] */
+ token_p st_ct; /* curtoken */
+ result_t st_do[LONGESTPATTERN]; /* dollar[] */
+ struct reginfo st_mr[NREGS]; /* machregs[] */
+ int st_ne; /* nemlines */
+ struct emline st_el[MAXEMLINES]; /* emlines[] */
+ struct emline *st_em; /* emp */
+ struct emline *st_se; /* saveemp */
+ int st_tl; /* tokpatlen */
+ int st_ns; /* nstab */
+} state_t,*state_p;
--- /dev/null
+#ifndef NORCSID
+static char rcsid[] = "$Header$";
+#endif
+
+#include "assert.h"
+#include <stdio.h>
+#include "param.h"
+#include "tables.h"
+#include "types.h"
+#include <cgg_cg.h>
+#include "data.h"
+#include "result.h"
+#include "extern.h"
+
+/*
+ * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ *
+ * This product is part of the Amsterdam Compiler Kit.
+ *
+ * Permission to use, sell, duplicate or disclose this software must be
+ * obtained in writing. Requests for such permissions may be sent to
+ *
+ * Dr. Andrew S. Tanenbaum
+ * Wiskundig Seminarium
+ * Vrije Universiteit
+ * Postbox 7161
+ * 1007 MC Amsterdam
+ * The Netherlands
+ *
+ * Author: Hans van Staveren
+ */
+
+string myalloc();
+unsigned codegen();
+
+match(tp,tep,optexp) register token_p tp; register set_p tep; {
+ register bitno;
+ token_p ct;
+ result_t result;
+
+ if (tp->t_token == -1) { /* register frame */
+ bitno = tp->t_att[0].ar;
+ if (tep->set_val[bitno>>4]&(1<<(bitno&017)))
+ if (tep->set_val[0]&1 || getrefcount(tp->t_att[0].ar)<=1)
+ goto oklabel;
+ return(0);
+ } else { /* token frame */
+ bitno = tp->t_token+NREGS;
+ if ((tep->set_val[bitno>>4]&(1<<(bitno&017)))==0)
+ return(0);
+ }
+ oklabel:
+ if (optexp==0)
+ return(1);
+ ct=curtoken;
+ curtoken=tp;
+ result=compute(&enodes[optexp]);
+ curtoken=ct;
+ return(result.e_v.e_con);
+}
+
+instance(instno,token) register token_p token; {
+ register inst_p inp;
+ int i;
+ register token_p tp;
+ struct reginfo *rp;
+ int regno;
+ result_t result;
+
+ if (instno==0) {
+ token->t_token = 0;
+ for(i=0;i<TOKENSIZE;i++)
+ token->t_att[i].aw=0;
+ return;
+ }
+ inp= &tokeninstances[instno];
+ switch(inp->in_which) {
+ default:
+ assert(FALSE);
+ case IN_COPY:
+ tp= &fakestack[stackheight-inp->in_info[0]];
+ if (inp->in_info[1]==0) {
+ *token = *tp;
+ } else {
+ token->t_token= -1;
+#if MAXMEMBERS!=0
+ assert(tp->t_token == -1);
+ rp = &machregs[tp->t_att[0].ar];
+ token->t_att[0].ar=rp->r_members[inp->in_info[1]-1];
+#else
+ assert(FALSE);
+#endif
+ }
+ return;
+ case IN_MEMB:
+ tp= &fakestack[stackheight-inp->in_info[0]];
+ assert(inp->in_info[1]!=0);
+ assert(tp->t_token>0);
+ token->t_token= -1;
+ assert(tokens[tp->t_token].t_type[inp->in_info[1]-1] == EV_REG);
+ token->t_att[0].ar=tp->t_att[inp->in_info[1]-1].ar;
+ return;
+ case IN_RIDENT:
+ token->t_token= -1;
+ token->t_att[0].ar= inp->in_info[0];
+ return;
+ case IN_ALLOC:
+ token->t_token= -1;
+ regno=allreg[inp->in_info[0]];
+#if MAXMEMBERS!=0
+ if (inp->in_info[1])
+ regno=machregs[regno].r_members[inp->in_info[1]-1];
+#endif
+ token->t_att[0].ar = regno;
+ return;
+#ifdef REGVARS
+ case IN_S_DESCR:
+ case IN_D_DESCR:
+ result=compute(&enodes[inp->in_info[1]]);
+ assert(result.e_typ==EV_INT);
+ if ((regno=isregvar(result.e_v.e_con)) > 0) {
+ token->t_token = -1;
+ token->t_att[0].ar = regno;
+ for(i=1;i<TOKENSIZE;i++)
+ token->t_att[i].aw = 0;
+ return;
+ }
+ /* fall through */
+#endif
+ case IN_DESCR:
+ token->t_token=inp->in_info[0];
+ for (i=0;i<TOKENSIZE;i++)
+ if (inp->in_info[i+1]==0) {
+ assert(tokens[token->t_token].t_type[i]==0);
+ token->t_att[i].aw=0;
+ } else {
+ result=compute(&enodes[inp->in_info[i+1]]);
+ assert(tokens[token->t_token].t_type[i]==result.e_typ);
+ if (result.e_typ==EV_INT)
+ token->t_att[i].aw=result.e_v.e_con;
+ else if (result.e_typ==EV_ADDR)
+ token->t_att[i].aa= result.e_v.e_addr;
+ else
+ token->t_att[i].ar=result.e_v.e_reg;
+ }
+ return;
+ }
+}
+
+cinstance(instno,token,tp,regno) register token_p token,tp; {
+ register inst_p inp;
+ int i;
+ struct reginfo *rp;
+ result_t result;
+ int sh; /* saved stackheight */
+
+ assert(instno!=0);
+ inp= &tokeninstances[instno];
+ switch(inp->in_which) {
+ default:
+ assert(FALSE);
+ case IN_COPY:
+ assert(inp->in_info[0] == 1);
+ if (inp->in_info[1]==0) {
+ *token = *tp;
+ } else {
+ token->t_token= -1;
+#if MAXMEMBERS!=0
+ assert(tp->t_token == -1);
+ rp = &machregs[tp->t_att[0].ar];
+ token->t_att[0].ar=rp->r_members[inp->in_info[1]-1];
+#else
+ assert(FALSE);
+#endif
+ }
+ return;
+ case IN_MEMB:
+ assert(inp->in_info[0] == 1);
+ token->t_token= -1;
+ assert(tp->t_token>0);
+ assert(tokens[tp->t_token].t_type[inp->in_info[1]-1] == EV_REG);
+ token->t_att[0].ar=tp->t_att[inp->in_info[1]-1].ar;
+ return;
+ case IN_RIDENT:
+ token->t_token= -1;
+ token->t_att[0].ar= inp->in_info[0];
+ return;
+ case IN_ALLOC:
+ token->t_token= -1;
+ assert(inp->in_info[0]==0);
+#if MAXMEMBERS!=0
+ if (inp->in_info[1])
+ regno=machregs[regno].r_members[inp->in_info[1]-1];
+#endif
+ token->t_att[0].ar = regno;
+ return;
+#ifdef REGVARS
+ case IN_S_DESCR:
+ case IN_D_DESCR:
+ result=compute(&enodes[inp->in_info[1]]);
+ assert(result.e_typ==EV_INT);
+ if ((regno=isregvar(result.e_v.e_con)) > 0) {
+ token->t_token = -1;
+ token->t_att[0].ar = regno;
+ for(i=1;i<TOKENSIZE;i++)
+ token->t_att[i].aw = 0;
+ return;
+ }
+ /* fall through */
+#endif
+ case IN_DESCR:
+ sh = stackheight;
+ stackheight = tp - fakestack + 1;
+ token->t_token=inp->in_info[0];
+ for (i=0;i<TOKENSIZE;i++)
+ if (inp->in_info[i+1]==0) {
+ assert(tokens[token->t_token].t_type[i]==0);
+ token->t_att[i].aw=0;
+ } else {
+ result=compute(&enodes[inp->in_info[i+1]]);
+ assert(tokens[token->t_token].t_type[i]==result.e_typ);
+ if (result.e_typ==EV_INT)
+ token->t_att[i].aw=result.e_v.e_con;
+ else if (result.e_typ==EV_ADDR)
+ token->t_att[i].aa= result.e_v.e_addr;
+ else
+ token->t_att[i].ar=result.e_v.e_reg;
+ }
+ stackheight = sh;
+ return;
+ }
+}
+
+eqtoken(tp1,tp2) token_p tp1,tp2; {
+ register i;
+ register tkdef_p tdp;
+
+ if (tp1->t_token!=tp2->t_token)
+ return(0);
+ if (tp1->t_token==0)
+ return(1);
+ if (tp1->t_token==-1) {
+ if (tp1->t_att[0].ar!=tp2->t_att[0].ar)
+ return(0);
+ return(1);
+ }
+ tdp = &tokens[tp1->t_token];
+ for (i=0;i<TOKENSIZE;i++)
+ switch(tdp->t_type[i]) {
+ default:
+ return(1);
+ case EV_INT:
+ if (tp1->t_att[i].aw != tp2->t_att[i].aw)
+ return(0);
+ break;
+ case EV_REG:
+ if (tp1->t_att[i].ar != tp2->t_att[i].ar)
+ return(0);
+ break;
+ case EV_ADDR:
+ if (strcmp(tp1->t_att[i].aa.ea_str, tp2->t_att[i].aa.ea_str))
+ return(0);
+ if (tp1->t_att[i].aa.ea_off!=tp2->t_att[i].aa.ea_off)
+ return(0);
+ break;
+ }
+ return(1);
+}
+
+distance(cindex) {
+ register char *bp;
+ register i;
+ register token_p tp;
+ int tokexp,tpl;
+ int expsize,toksize,exact;
+ int xsekt=0;
+
+ bp = &coderules[cindex];
+#ifndef NDEBUG
+ if (*bp==DO_DLINE) {
+ ++bp;
+ getint(i,bp);
+ }
+#endif
+ switch( (*bp)&037 ) {
+ default:
+ return(stackheight==0 ? 0 : 100);
+ case DO_MATCH:
+ break;
+ case DO_XXMATCH:
+ xsekt++;
+ case DO_XMATCH:
+ xsekt++;
+ break;
+ }
+ tpl= ((*bp++)>>5)&07;
+ if (stackheight < tpl) {
+ if (xsekt)
+ return(MAXINT);
+ tpl = stackheight;
+ } else
+ if (stackheight != tpl && xsekt==2)
+ return(MAXINT);
+ exact=0;
+ tp= &fakestack[stackheight-1];
+ for (i=0;i<tpl;i++,tp--) {
+ getint(tokexp,bp);
+ if (!match(tp, &machsets[tokexp], 0)) {
+ if (xsekt)
+ return(MAXINT);
+ expsize = ssize(tokexp);
+ toksize = tsize(tp);
+ if (expsize>toksize)
+ return(100);
+ if (expsize<toksize)
+ return(99-i);
+ } else
+ exact++;
+ }
+ if (exact==tpl) {
+ if (xsekt)
+ return(0);
+ return(10-exact);
+ }
+ return(20-exact);
+}
+
+unsigned costcalc(cost) cost_t cost; {
+ extern unsigned cc1,cc2,cc3,cc4;
+
+ return(cost.ct_space*cc1/cc2 + cost.ct_time*cc3/cc4);
+}
+
+ssize(tokexpno) {
+
+ return(machsets[tokexpno].set_size);
+}
+
+tsize(tp) register token_p tp; {
+
+ if (tp->t_token==-1)
+ return(machregs[tp->t_att[0].ar].r_size);
+ return(tokens[tp->t_token].t_size);
+}
+
+#ifdef MAXSPLIT
+instsize(tinstno,tp) token_p tp; {
+ inst_p inp;
+ struct reginfo *rp;
+
+ inp = &tokeninstances[tinstno];
+ switch(inp->in_which) {
+ default:
+ assert(FALSE);
+ case IN_COPY:
+ assert(inp->in_info[0]==1);
+#if MAXMEMBERS!=0
+ if (inp->in_info[1]==0)
+#endif
+ return(tsize(tp));
+#if MAXMEMBERS!=0
+ else {
+ assert(tp->t_token == -1);
+ rp = &machregs[tp->t_att[0].ar];
+ return(machregs[rp->r_members[inp->in_info[1]-1]].r_size);
+ }
+#endif
+ case IN_RIDENT:
+ return(machregs[inp->in_info[0]].r_size);
+ case IN_ALLOC:
+ assert(FALSE); /* cannot occur in splitting coercion */
+ case IN_DESCR:
+ case IN_S_DESCR:
+ case IN_D_DESCR:
+ return(tokens[inp->in_info[0]].t_size);
+ }
+}
+#endif MAXSPLIT
+
+tref(tp,amount) register token_p tp; {
+ register i;
+ register tkdef_p tdp;
+
+ if (tp->t_token==-1)
+ chrefcount(tp->t_att[0].ar,amount,FALSE);
+ else {
+ tdp= &tokens[tp->t_token];
+ for(i=0;i<TOKENSIZE;i++)
+ if (tdp->t_type[i]==EV_REG)
+ chrefcount(tp->t_att[i].ar,amount,FALSE);
+ }
+}
+
+#define MAXSAVE 10
+
+#ifdef MAXSPLIT
+split(tp,ip,ply,toplevel) token_p tp; register int *ip; {
+ register c2_p cp;
+ token_t savestack[MAXSAVE];
+ int ok;
+ register i;
+ int diff;
+ token_p stp;
+ int tpl;
+
+ for (cp=c2coercs;cp->c2_texpno>=0; cp++) {
+ if (!match(tp,&machsets[cp->c2_texpno],0))
+ continue;
+ ok=1;
+ for (i=0; ok && i<cp->c2_nsplit;i++) {
+ if (ip[i]==0)
+ goto found;
+ if (instsize(cp->c2_repl[i],tp) != ssize(ip[i]))
+ ok=0;
+ }
+ goto found;
+ }
+ return(0);
+found:
+ assert(stackheight+cp->c2_nsplit-1<MAXFSTACK);
+ stp = &fakestack[stackheight-1];
+ diff = stp - tp;
+ assert(diff<=MAXSAVE);
+ for (i=1;i<=diff;i++)
+ savestack[i-1] = tp[i]; /* save top of stack */
+ stackheight -= diff;
+ tpl = tokpatlen;
+ tokpatlen = 1;
+ codegen(&coderules[cp->c2_codep],ply,toplevel,MAXINT,0);
+ tokpatlen = tpl;
+ for (i=0;i<diff;i++) /* restore top of stack */
+ fakestack[stackheight++] = savestack[i];
+ return(cp->c2_nsplit);
+}
+#endif MAXSPLIT
+
+unsigned docoerc(tp,cp,ply,toplevel,forced) token_p tp; register c3_p cp; {
+ token_t savestack[MAXSAVE];
+ token_p stp;
+ register int i,diff;
+ unsigned cost;
+ int tpl; /* saved tokpatlen */
+
+ stp = &fakestack[stackheight-1];
+ diff = stp -tp;
+ assert(diff<=MAXSAVE);
+#ifndef NDEBUG
+ if (diff!=0 && Debug>1)
+ fprintf(stderr,"Saving %d items from fakestack\n",diff);
+#endif
+ for (i=1;i<=diff;i++)
+ savestack[i-1] = tp[i];
+ stackheight -= diff;
+ tpl = tokpatlen;
+ tokpatlen = 1;
+ cost = codegen(&coderules[cp->c3_codep],ply,toplevel,MAXINT,forced);
+ tokpatlen = tpl;
+#ifndef NDEBUG
+ if (diff!=0 && Debug>1)
+ fprintf(stderr,"Restoring %d items to fakestack(%d)\n",diff,stackheight);
+#endif
+ for (i=0;i<diff;i++)
+ fakestack[stackheight++] = savestack[i];
+ nallreg = 0;
+ return(cost);
+}
+
+unsigned stackupto(limit,ply,toplevel) token_p limit; {
+ token_t savestack[MAXFSTACK];
+ token_p stp;
+ int i,diff;
+ int tpl; /* saved tokpatlen */
+ int nareg; /* saved nareg */
+ int areg[MAXALLREG];
+ register c1_p cp;
+ register token_p tp;
+ unsigned totalcost=0;
+ struct reginfo *rp,**rpp;
+
+ for (tp=fakestack;tp<=limit;limit--) {
+ for (cp=c1coercs;cp->c1_texpno>=0; cp++) {
+ if (match(tp,&machsets[cp->c1_texpno],cp->c1_expr)) {
+ if (cp->c1_prop>=0) {
+ for (rpp=reglist[cp->c1_prop];
+ (rp = *rpp)!=0 &&
+ getrefcount(rp-machregs)!=0;
+ rpp++)
+ ;
+ if (rp==0)
+ continue;
+ /* look for other possibility */
+ }
+ stp = &fakestack[stackheight-1];
+ diff = stp -tp;
+ assert(diff<=MAXFSTACK);
+ for (i=1;i<=diff;i++)
+ savestack[i-1] = tp[i];
+ stackheight -= diff;
+ tpl = tokpatlen;
+ tokpatlen = 1;
+ nareg = nallreg;
+ for (i=0;i<nareg;i++)
+ areg[i] = allreg[i];
+ if (cp->c1_prop>=0) {
+ nallreg=1; allreg[0] = rp-machregs;
+ chrefcount(allreg[0],1,FALSE);
+ } else
+ nallreg=0;
+ totalcost+= codegen(&coderules[cp->c1_codep],ply,toplevel,MAXINT,0);
+ tokpatlen = tpl;
+ for (i=0;i<diff;i++)
+ fakestack[stackheight++] = savestack[i];
+ nallreg=nareg;
+ for (i=0;i<nareg;i++)
+ allreg[i] = areg[i];
+ goto contin;
+ }
+ }
+ assert(FALSE);
+ contin: ;
+ }
+ return(totalcost);
+}
+
+c3_p findcoerc(tp,tep) token_p tp; set_p tep; {
+ register c3_p cp;
+ token_t rtoken;
+ register i;
+ register struct reginfo **rpp;
+
+ for (cp=c3coercs;cp->c3_texpno>=0; cp++) {
+ if (tp!=(token_p) 0) {
+ if (cp->c3_texpno==0)
+ continue;
+ if (!match(tp,&machsets[cp->c3_texpno],cp->c3_expr))
+ continue;
+ } else {
+ if (cp->c3_texpno!=0)
+ continue;
+ }
+ if (cp->c3_prop==0) { /* no reg needed */
+ cinstance(cp->c3_repl,&rtoken,tp,0);
+ if (match(&rtoken,tep,0))
+ return(cp);
+ } else {
+ curreglist = (rl_p) myalloc(sizeof (rl_t));
+ curreglist->rl_n = 0;
+ for (rpp=reglist[cp->c3_prop];*rpp;rpp++) {
+ i = *rpp - machregs;
+ cinstance(cp->c3_repl,&rtoken,tp,i);
+ if (match(&rtoken,tep,0))
+ curreglist->rl_list[curreglist->rl_n++] = i;
+ }
+ if (curreglist->rl_n != 0)
+ return(cp);
+ myfree(curreglist);
+ }
+ }
+ return(0); /* nothing found */
+}
+
+itokcost() {
+ register tkdef_p tdp;
+
+ for(tdp=tokens+1;tdp->t_size!=0;tdp++)
+ tdp->t_cost.ct_space = costcalc(tdp->t_cost);
+}
+
+error(s,a1,a2,a3,a4,a5,a6,a7,a8) char *s; {
+
+ fatal(s,a1,a2,a3,a4,a5,a6,a7,a8);
+}
+
+fatal(s,a1,a2,a3,a4,a5,a6,a7,a8) char *s; {
+
+ fprintf(stderr,"Error: ");
+ fprintf(stderr,s,a1,a2,a3,a4,a5,a6,a7,a8);
+ fprintf(stderr,"\n");
+#ifdef TABLEDEBUG
+ ruletrace();
+#endif
+ out_finish();
+ abort();
+ exit(-1);
+}
+
+#ifdef TABLEDEBUG
+
+ruletrace() {
+ register i;
+ extern int tablelines[MAXTDBUG];
+ extern int ntableline;
+ extern char *tablename;
+
+ fprintf(stderr,"Last code rules used\n");
+ i=ntableline-1;
+ while(i!=ntableline) {
+ if (i<0)
+ i += MAXTDBUG;
+ if (tablelines[i]!=0)
+ fprintf(stderr,"\%d: \"%s\", line %d\n",i,tablename,tablelines[i]);
+ i--;
+ }
+}
+#endif
+
+#ifndef NDEBUG
+badassertion(asstr,file,line) char *asstr, *file; {
+
+ fatal("\"%s\", line %d:Assertion \"%s\" failed",file,line,asstr);
+}
+#endif
+
+max(a,b) {
+
+ return(a>b ? a : b);
+}
--- /dev/null
+/* $Header$ */
+
+#ifndef TEM_WSIZE
+TEM_WSIZE should be defined at this point
+#endif
+#ifndef TEM_PSIZE
+TEM_PSIZE should be defined at this point
+#endif
+#if TEM_WSIZE>4 || TEM_PSIZE>4
+Implementation will not be correct unless a long integer
+has more then 4 bytes of precision.
+#endif
+
+typedef char byte;
+typedef char * string;
+
+#if TEM_WSIZE>2 || TEM_PSIZE>2
+#define full long
+#else
+#define full int
+#endif
+
+#if TEM_WSIZE>2
+#define word long
+#else
+#define word int
+#endif
--- /dev/null
+#ifndef NORCSID
+static char rcsid[] = "$Header$";
+#endif
+
+#include "param.h"
+#include "tables.h"
+#include "types.h"
+#include <cgg_cg.h>
+#include "data.h"
+#include "result.h"
+
+/*
+ * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ *
+ * This product is part of the Amsterdam Compiler Kit.
+ *
+ * Permission to use, sell, duplicate or disclose this software must be
+ * obtained in writing. Requests for such permissions may be sent to
+ *
+ * Dr. Andrew S. Tanenbaum
+ * Wiskundig Seminarium
+ * Vrije Universiteit
+ * Postbox 7161
+ * 1007 MC Amsterdam
+ * The Netherlands
+ *
+ * Author: Hans van Staveren
+ */
+
+int stackheight = 0;
+token_t fakestack[MAXFSTACK];
+int nallreg = 0;
+int allreg[MAXALLREG];
+token_p curtoken = (token_p) 0;
+result_t dollar[LONGESTPATTERN];
+int nemlines =0;
+struct emline emlines[MAXEMLINES];
+struct emline *emp=emlines;
+struct emline *saveemp;
+int tokpatlen;
+rl_p curreglist;