|
@@ -0,0 +1,666 @@
|
|
|
+#include "assert.h"
|
|
|
+#include "param.h"
|
|
|
+#include "tables.h"
|
|
|
+#include "types.h"
|
|
|
+#include <cg_pattern.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 SHORTCUT /* Stop searching at distance 0 */
|
|
|
+
|
|
|
+#if NREGS >= MAXRULE
|
|
|
+#define MAXPOS NREGS
|
|
|
+#else
|
|
|
+#define MAXPOS MAXRULE
|
|
|
+#endif
|
|
|
+
|
|
|
+#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();
|
|
|
+
|
|
|
+#ifdef NDEBUG
|
|
|
+#define DEBUG()
|
|
|
+#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");goto doreturn;}
|
|
|
+#define CHKCOST() {if (totalcost>=costlimit) BROKE();}
|
|
|
+
|
|
|
+unsigned codegen(codep,ply,toplevel,costlimit,forced) byte *codep; unsigned costlimit; {
|
|
|
+#ifndef NDEBUG
|
|
|
+ byte *origcp=codep;
|
|
|
+ static int level=0;
|
|
|
+#endif
|
|
|
+ unsigned totalcost = 0;
|
|
|
+ byte *bp;
|
|
|
+ int n;
|
|
|
+ unsigned mindistance,dist;
|
|
|
+ register i;
|
|
|
+ int cindex;
|
|
|
+ int npos,npos2,pos[MAXPOS],pos2[MAXPOS];
|
|
|
+#ifdef STONSTACK
|
|
|
+ state_t state;
|
|
|
+#define SAVEST savestatus(&state)
|
|
|
+#define RESTST restorestatus(&state)
|
|
|
+#define FREEST /* nothing */
|
|
|
+#else
|
|
|
+ state_p state;
|
|
|
+#define SAVEST state=savestatus()
|
|
|
+#define RESTST restorestatus(state)
|
|
|
+#define FREEST freestatus(state)
|
|
|
+#endif
|
|
|
+ unsigned mincost,t;
|
|
|
+ int texpno,nodeno;
|
|
|
+ token_p tp;
|
|
|
+ tkdef_p tdp;
|
|
|
+ int tinstno;
|
|
|
+ struct reginfo *rp,**rpp;
|
|
|
+ token_t token,mtoken,token2;
|
|
|
+ int propno;
|
|
|
+ int exactmatch;
|
|
|
+ int j;
|
|
|
+ int decision;
|
|
|
+ int stringno;
|
|
|
+ result_t result;
|
|
|
+ cost_t cost;
|
|
|
+ int size,lsize,repllen;
|
|
|
+ int tokexp[MAXPATTERN];
|
|
|
+ int nregneeded;
|
|
|
+ token_p regtp[MAXCREG];
|
|
|
+ c3_p regcp[MAXCREG];
|
|
|
+ rl_p regls[MAXCREG];
|
|
|
+ c3_p cp,findcoerc();
|
|
|
+ int sret;
|
|
|
+ token_t reptoken[MAXREPLLEN];
|
|
|
+ int emrepllen,eminstr;
|
|
|
+ int inscoerc=0;
|
|
|
+ int stackpad;
|
|
|
+ struct perm *tup,*ntup,*besttup,*tuples();
|
|
|
+
|
|
|
+#ifndef NDEBUG
|
|
|
+ level++;
|
|
|
+ DEBUG("Entering codegen");
|
|
|
+#endif
|
|
|
+ for (;;) {
|
|
|
+ switch( (*codep++)&037 ) {
|
|
|
+ default:
|
|
|
+ assert(FALSE);
|
|
|
+ /* NOTREACHED */
|
|
|
+ case DO_NEXTEM:
|
|
|
+ DEBUG("NEXTEM");
|
|
|
+ tokpatlen = 0;
|
|
|
+ nallreg=0;
|
|
|
+ if (toplevel) {
|
|
|
+ garbage_collect();
|
|
|
+ totalcost=0;
|
|
|
+ } else {
|
|
|
+ if (--ply <= 0)
|
|
|
+ goto doreturn;
|
|
|
+ }
|
|
|
+ if (stackheight>MAXFSTACK-7)
|
|
|
+ totalcost += stackupto(&fakestack[6],ply,toplevel);
|
|
|
+ bp = nextem(toplevel);
|
|
|
+ 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++;
|
|
|
+ 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) {
|
|
|
+#ifdef SHORTCUT
|
|
|
+ if(dist==0)
|
|
|
+ goto gotit;
|
|
|
+#endif
|
|
|
+ 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) {
|
|
|
+ totalcost += mincost;
|
|
|
+ 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:
|
|
|
+ DEBUG("XMATCH");
|
|
|
+ tokpatlen=(codep[-1]>>5)&07;
|
|
|
+ for (i=0;i<tokpatlen;i++)
|
|
|
+ getint(tokexp[i],codep);
|
|
|
+ tokexp[i]=0;
|
|
|
+ break; /* match already checked by distance() */
|
|
|
+ case DO_MATCH:
|
|
|
+ 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]]);
|
|
|
+ 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 {
|
|
|
+ assert(nregneeded<MAXCREG);
|
|
|
+ regtp[nregneeded] = tp;
|
|
|
+ regcp[nregneeded] = cp;
|
|
|
+ regls[nregneeded] = curreglist;
|
|
|
+ nregneeded++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ i++; tp--;
|
|
|
+ }
|
|
|
+ if (tokpatlen>stackheight) {
|
|
|
+ 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;
|
|
|
+ tp = &fakestack[stackpad-1];
|
|
|
+ while (i<tokpatlen && tp>=fakestack) {
|
|
|
+ cp = findcoerc((token_p) 0, &machsets[tokexp[i]]);
|
|
|
+ if (cp==0) {
|
|
|
+ assert(!toplevel);
|
|
|
+ for (j=0;j<nregneeded;j++)
|
|
|
+ myfree(regls[j]);
|
|
|
+ totalcost=INFINITY;
|
|
|
+ BROKE();
|
|
|
+ }
|
|
|
+ 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++;
|
|
|
+ }
|
|
|
+ i++; tp--;
|
|
|
+ }
|
|
|
+ } 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) {
|
|
|
+ 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)
|
|
|
+ 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);
|
|
|
+ if (stackpad!=tokpatlen) {
|
|
|
+ if (stackpad) {
|
|
|
+ if (costlimit<MAXINT) {
|
|
|
+ totalcost = costlimit+1;
|
|
|
+ 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;
|
|
|
+ BROKE();
|
|
|
+ }
|
|
|
+ for (i=0;i<nregneeded;i++)
|
|
|
+ totalcost += docoerc(regtp[i],regcp[i],ply,toplevel,besttup->p_rar[i]);
|
|
|
+ myfree(besttup);
|
|
|
+ break;
|
|
|
+ case DO_REMOVE:
|
|
|
+ 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+2;rp<machregs+NREGS;rp++)
|
|
|
+ if (match(&rp->r_contents,&machsets[texpno],nodeno))
|
|
|
+ rp->r_contents.t_token=0;
|
|
|
+ break;
|
|
|
+ case DO_RREMOVE: /* register remove */
|
|
|
+ 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_con)
|
|
|
+ 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_con)
|
|
|
+ goto gotone;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ gotone:
|
|
|
+ /* investigate possible coercion to register */
|
|
|
+ totalcost += stackupto(tp,ply,toplevel);
|
|
|
+ CHKCOST();
|
|
|
+ break;
|
|
|
+ case DO_DEALLOCATE:
|
|
|
+ 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:
|
|
|
+ DEBUG("REALLOCATE");
|
|
|
+ for(rp=machregs;rp<machregs+NREGS;rp++)
|
|
|
+ if(rp->r_tcount) {
|
|
|
+ rp->r_refcount -= rp->r_tcount;
|
|
|
+ rp->r_tcount = 0;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case DO_ALLOCATE:
|
|
|
+ DEBUG("ALLOCATE");
|
|
|
+ if (codep[-1]&32) {
|
|
|
+ getint(propno,codep);
|
|
|
+ getint(tinstno,codep);
|
|
|
+ } else {
|
|
|
+ getint(propno,codep);
|
|
|
+ tinstno=0;
|
|
|
+ }
|
|
|
+ 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) {
|
|
|
+ totalcost = INFINITY;
|
|
|
+ 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) {
|
|
|
+ totalcost = INFINITY;
|
|
|
+ BROKE();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ decision = forced;
|
|
|
+ if (getrefcount(decision)!=0) {
|
|
|
+ totalcost = INFINITY;
|
|
|
+ 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_LOUTPUT:
|
|
|
+ DEBUG("LOUTPUT");
|
|
|
+ getint(stringno,codep);
|
|
|
+ getint(nodeno,codep);
|
|
|
+ if (toplevel) {
|
|
|
+ gencode(codestrings[stringno]);
|
|
|
+ genexpr(nodeno);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case DO_ROUTPUT:
|
|
|
+ DEBUG("ROUTPUT");
|
|
|
+ i=((codep[-1]>>5)&07);
|
|
|
+ do {
|
|
|
+ getint(stringno,codep);
|
|
|
+ if (toplevel) {
|
|
|
+ gencode(codestrings[stringno]);
|
|
|
+ gennl();
|
|
|
+ }
|
|
|
+ } while (i--);
|
|
|
+ break;
|
|
|
+ case DO_MOVE:
|
|
|
+ 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_ERASE:
|
|
|
+ DEBUG("ERASE");
|
|
|
+ getint(nodeno,codep);
|
|
|
+ result=compute(&enodes[nodeno]);
|
|
|
+ assert(result.e_typ==EV_REG);
|
|
|
+ erasereg(result.e_v.e_reg);
|
|
|
+ break;
|
|
|
+ case DO_TOKREPLACE:
|
|
|
+ DEBUG("TOKREPLACE");
|
|
|
+ assert(stackheight>=tokpatlen);
|
|
|
+ repllen=(codep[-1]>>5)&07;
|
|
|
+ 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:
|
|
|
+ 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_STR:
|
|
|
+ emp[i].em_optyp = OPSYMBOL;
|
|
|
+ emp[i].em_soper = result.e_v.e_str;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!toplevel)
|
|
|
+ ply += emrepllen;
|
|
|
+ break;
|
|
|
+ case DO_COST:
|
|
|
+ DEBUG("COST");
|
|
|
+ getint(cost.c_size,codep);
|
|
|
+ getint(cost.c_time,codep);
|
|
|
+ totalcost += costcalc(cost);
|
|
|
+ CHKCOST();
|
|
|
+ break;
|
|
|
+#ifdef REGVARS
|
|
|
+ case DO_PRETURN:
|
|
|
+ if (toplevel)
|
|
|
+ regreturn(); /* in mach.c */
|
|
|
+ break;
|
|
|
+#endif
|
|
|
+ case DO_RETURN:
|
|
|
+ DEBUG("RETURN");
|
|
|
+ assert(origcp!=startupcode);
|
|
|
+ doreturn:
|
|
|
+#ifndef NDEBUG
|
|
|
+ level--;
|
|
|
+#endif
|
|
|
+ return(totalcost);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|