123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974 |
- /*
- * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
- * See the copyright notice in the ACK home directory, in the file "Copyright".
- *
- * Author: Hans van Staveren
- */
- #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"
- #include "codegen.h"
- #include "utils.h"
- #include "salloc.h"
- #include "subr.h"
- #include "nextem.h"
- #include "fillem.h"
- #include "reg.h"
- #include "move.h"
- #include "gencode.h"
- #include "compute.h"
- #include "codegen.h"
- #include "mach_dep.h"
- #define ALLOW_NEXTEM /* code generator is allowed new try of NEXTEM
- in exceptional cases */
- byte startupcode[] = { DO_NEXTEM };
- #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 || !paniced);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(byte *codep, int ply, int toplevel, unsigned int costlimit, int forced)
- {
- #ifndef NDEBUG
- byte *origcp=codep;
- static int level=0;
- #endif
- unsigned totalcost = 0;
- int inscoerc=0;
- int procarg[MAXPROCARG+1];
- #ifdef ALLOW_NEXTEM
- static int paniced;
- char *savebp = 0;
- #endif
- state_t state;
- #define SAVEST savestatus(&state)
- #define RESTST restorestatus(&state)
- #define FREEST /* nothing */
- #ifdef TABLEDEBUG
- extern char *tablename;
- #endif
- #ifndef NDEBUG
- assert(costlimit <= INFINITY);
- level++;
- DEBUG("Entering codegen");
- if (Debug > 1) fprintf(stderr, "toplevel = %d\n", toplevel);
- #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;
- int 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
- if (toplevel) paniced=0;
- savebp = nextem(toplevel);
- panic:
- if (toplevel) totalcost = 0;
- 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
- if (! toplevel) {
- ply -= emp-saveemp+1;
- if (ply <= 0) ply = 1;
- }
- n = *bp++;
- if (n==0) { /* "procedure" */
- int j, nargs;
- getint(i,bp);
- getint(nargs,bp);
- assert(nargs <= MAXPROCARG);
- for (j = 0; j < nargs; j++) {
- getint(procarg[j],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
- #ifdef ALLOW_NEXTEM
- || paniced
- #endif
- ) {
- if (dist<mindistance) {
- if(dist==0)
- goto gotit;
- npos=0;
- mindistance = dist;
- }
- #ifdef ALLOW_NEXTEM
- if (dist < MAXINT)
- #endif
- 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;
- assert(mincost <= INFINITY);
- for(i=0;i<npos;i++) {
- t=codegen(&coderules[pos[i]],ply,FALSE,
- costlimit<MAXINT?mincost:MAXINT,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: {
- int 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: {
- int i;
- int j;
- unsigned mincost,t;
- token_p tp;
- int size,lsize;
- int tokexp[MAXPATLEN];
- int nregneeded;
- token_p regtp[MAXCREG];
- c3_p regcp[MAXCREG];
- rl_p regls[MAXCREG];
- c3_p cp;
- #ifdef MAXSPLIT
- int sret;
- #endif
- int stackpad = 0;
- struct perm *tup,*ntup,*besttup;
- 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 0x%x at position %d\n",(unsigned)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((string) (regls[j]));
- #ifndef ALLOW_NEXTEM
- assert(!toplevel);
- BROKE();
- #else
- assert(!(toplevel&&paniced));
- if (paniced) goto normalfailed;
- totalcost = INFINITY;
- for (i=0;i<stackheight-stackpad;i++)
- fakestack[i] = fakestack[i+stackpad];
- stackheight -= stackpad;
- goto doreturn;
- #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]);
- fprintf(stderr, "totalcost = %u, costlimit = %u, mincost = %u\n",
- totalcost, costlimit, mincost);
- }
- #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]);
- #ifndef NDEBUG
- if (Debug > 1) fprintf(stderr, "cost after coercions: %u\n", t);
- #endif
- if ( t<mincost && tokpatlen<=stackheight ) {
- #ifndef NDEBUG
- if (Debug>2)
- fprintf(stderr,"Continuing match after coercions\n");
- #endif
- t += codegen(codep,ply,FALSE,mincost<MAXINT?mincost-t:MAXINT,0);
- }
- if ( t<mincost && tokpatlen<=stackheight ) {
- mincost = t;
- besttup = tup;
- } else
- myfree((string) tup);
- RESTST;
- }
- FREEST;
- for (i=0;i<nregneeded;i++)
- myfree((string)(regls[i]));
- if (totalcost+mincost>costlimit) {
- if (besttup)
- myfree((string)besttup);
- normalfailed: if (stackpad!=tokpatlen) {
- if (stackpad) {
- for (i=0;i<stackheight-stackpad;i++)
- fakestack[i] = fakestack[i+stackpad];
- stackheight -= stackpad;
- if (costlimit<MAXINT)
- BROKE();
- totalcost += stackupto(&fakestack[stackheight-1],ply,toplevel);
- } else
- totalcost += stackupto(fakestack,ply,toplevel);
- CHKCOST();
- goto nextmatch;
- }
- totalcost += mincost;
- for (i=0;i<stackheight-stackpad;i++)
- fakestack[i] = fakestack[i+stackpad];
- stackheight -= stackpad;
- BROKE();
- }
- for (i=0;i<nregneeded;i++)
- totalcost += docoerc(regtp[i],regcp[i],ply,toplevel,besttup->p_rar[i]);
- assert(totalcost <= costlimit);
- myfree((string)besttup);
- break;
- }
- case DO_TOSTACK:
- case DO_REMOVE: {
- int texpno,nodeno;
- token_p tp;
- struct reginfo *rp;
- int doremove = (codep[-1] & 037) == DO_REMOVE;
- extern int allsetno;
- DEBUG(doremove ? "REMOVE" : "TOSTACK");
- if (codep[-1]&32) {
- getint(texpno,codep);
- getint(nodeno,codep);
- } else {
- getint(texpno,codep);
- nodeno=0;
- }
- if (texpno == allsetno) {
- totalcost += stackupto(&fakestack[stackheight-tokpatlen-1],ply,toplevel);
- CHKCOST();
- if (doremove) for (rp=machregs;rp<machregs+NREGS;rp++)
- rp->r_contents.t_token=0;
- break;
- }
- 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;
- }
- if (doremove) for (rp=machregs;rp<machregs+NREGS;rp++) {
- if (rp->r_contents.t_token != 0 &&
- match(&rp->r_contents,&machsets[texpno],nodeno)) {
- #ifndef NDEBUG
- if (Debug > 1) fprintf(stderr, "killing reg %ld (%s)\n", (long)(rp-machregs), rp->r_repr ? codestrings[rp->r_repr] : "cc");
- #endif
- rp->r_contents.t_token=0;
- }
- }
- break;
- }
- case DO_KILLREG:
- case DO_RREMOVE: { /* register remove */
- int i;
- int nodeno;
- token_p tp;
- tkdef_p tdp;
- result_t result;
- int dokill = (codep[-1] & 037) == DO_KILLREG;
- DEBUG(dokill ? "KILLREG" : "RREMOVE");
- getint(nodeno,codep);
- compute(&enodes[nodeno], &result);
- if (result.e_typ!=EV_REG)
- break;
- if ( in_stack(result.e_v.e_reg) ) BROKE() ; /* Check aside-stack */
- if (dokill) {
- /* kill register, and kill condition codes if they are set to
- this register
- */
- machregs[result.e_v.e_reg].r_contents.t_token = 0;
- if (machregs[0].r_contents.t_token == -1 &&
- machregs[0].r_contents.t_att[0].ar == result.e_v.e_reg) {
- machregs[0].r_contents.t_token = 0;
- }
- }
- 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: {
- int 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: {
- int i;
- int j;
- int tinstno;
- int npos,npos2,pos[NREGS],pos2[NREGS];
- unsigned mincost,t;
- struct reginfo *rp,**rpp;
- token_t token,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((int)(rp-machregs), FALSE)==0) {
- pos[npos++] = rp-machregs;
- if (eqtoken(&rp->r_contents,&token))
- pos2[exactmatch++] = rp-machregs;
- }
- /*
- * 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 {
- if (paniced)
- fatal("No regs available");
- totalcost += stackupto( &fakestack[0],ply,toplevel);
- goto panic;
- }
- }
- totalcost += stackupto( &fakestack[0],ply,toplevel);
- CHKCOST();
- }
- } while (npos==0);
- if (!exactmatch && tinstno!=0) {
- /*
- * No exact match, but we were looking for a particular
- * token. Now try to find registers of which no
- * known contents is available (the others might still
- * be useful).
- */
- for (i=0;i<npos;i++)
- if (machregs[pos[i]].r_contents.t_token == 0) {
- pos2[exactmatch++] = pos[i];
- }
- }
- 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.
- */
- npos2=0;
- for(i=0;i<exactmatch;i++) {
- pos2[npos2++] = pos2[i];
- for(j=0;j<npos2-1;j++)
- if (eqregclass(pos2[j],pos2[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;
- decision=pos2[0];
- if (npos2!=1) {
- 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<MAXINT?mincost-t:MAXINT,0);
- if (t<mincost) {
- mincost=t;
- decision=pos2[j];
- }
- RESTST;
- }
- FREEST;
- if (totalcost+mincost>costlimit)
- BROKE();
- }
- } else {
- decision = forced;
- if (getrefcount(decision, FALSE)!=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: {
- int 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 < 100001 + MAXPROCARG);
- 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();
- CHKCOST();
- 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);
- compute(&enodes[nodeno], &result);
- 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: {
- int 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: {
- int i;
- int j;
- int nodeno;
- result_t result[MAXEMREPLLEN];
- 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;
- compute(&enodes[nodeno], &result[i]);
- }
- for (i=0;i<emrepllen;i++) {
- switch(result[i].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[i].e_v.e_con);
- emp[i].em_u.em_ioper = result[i].e_v.e_con;
- break;
- case EV_ADDR:
- emp[i].em_optyp = OPSYMBOL;
- emp[i].em_soper = ad2str(result[i].e_v.e_addr);
- break;
- }
- }
- if (!toplevel) {
- ply += emrepllen;
- #ifndef NDEBUG
- if (Debug > 4)
- fprintf(stderr, "ply becomes %d\n", ply);
- #endif
- }
- 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);
- #ifndef NDEBUG
- level--;
- #endif
- return(totalcost);
- #ifdef USE_TES
- case DO_LABDEF: {
- int index;
- DEBUG("LABDEF");
- getint(index,codep);
- if (toplevel) {
- swtxt();
- printlabel(index);
- }
- break;
- }
- #endif
- }
- }
- doreturn:
- #ifdef ALLOW_NEXTEM
- if (toplevel && totalcost == INFINITY && ! paniced) {
- DEBUG("PANIC!");
- totalcost += stackupto(&fakestack[stackheight-1], ply, toplevel);
- #ifndef NDEBUG
- if (Debug > 2)
- fprintf(stderr, "Stackheight = %d\n", stackheight);
- #endif
- paniced = 1;
- tokpatlen = 0;
- goto panic;
- }
- #endif
- #ifndef NDEBUG
- level--;
- #endif
- return(totalcost);
- }
- void readcodebytes()
- {
- #ifndef CODEINC
- int 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
- void initlset(char *f)
- {
- 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);
- }
- void 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') {
- int 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
|