2 static char rcsid[] = "$Id: subr.c,v 2.9 1994/06/24 13:24:27 ceriel Exp $";
10 #include <cg_pattern.h>
16 * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
17 * See the copyright notice in the ACK home directory, in the file "Copyright".
19 * Author: Hans van Staveren
22 extern string myalloc();
25 match(tp,tep,optexp) register token_p tp; register set_p tep; {
30 if (tp->t_token == -1) { /* register frame */
31 bitno = tp->t_att[0].ar+1;
32 if (tep->set_val[bitno>>4]&(1<<(bitno&017)))
33 if (tep->set_val[0]&1 || getrefcount(tp->t_att[0].ar, FALSE)<=1)
36 } else { /* token frame */
37 bitno = tp->t_token+NREGS+1;
38 if ((tep->set_val[bitno>>4]&(1<<(bitno&017)))==0)
46 result=compute(&enodes[optexp]);
48 return(result.e_v.e_con);
51 instance(instno,token) register token_p token; {
61 for(i=0;i<TOKENSIZE;i++)
65 inp= &tokeninstances[instno];
66 switch(inp->in_which) {
70 tp= &fakestack[stackheight-inp->in_info[0]];
71 if (inp->in_info[1]==0) {
76 if (tp->t_token == -1) {
77 rp = &machregs[tp->t_att[0].ar];
78 token->t_att[0].ar=rp->r_members[inp->in_info[1]-1];
81 assert(tokens[tp->t_token].t_type[inp->in_info[1]-1] == EV_REG);
82 token->t_att[0].ar=tp->t_att[inp->in_info[1]-1].ar;
90 token->t_att[0].ar= inp->in_info[0];
94 result=compute(&enodes[inp->in_info[0]]);
95 i=isregvar((long)result.e_v.e_con);
98 token->t_att[0].ar = i;
103 regno=allreg[inp->in_info[0]];
106 regno=machregs[regno].r_members[inp->in_info[1]-1];
108 token->t_att[0].ar = regno;
111 token->t_token=inp->in_info[0];
112 for (i=0;i<TOKENSIZE;i++)
113 if (inp->in_info[i+1]==0) {
114 assert(tokens[token->t_token].t_type[i]==0);
115 token->t_att[i].aw=0;
117 result=compute(&enodes[inp->in_info[i+1]]);
118 assert(tokens[token->t_token].t_type[i]==result.e_typ);
119 if (result.e_typ==EV_INT)
120 token->t_att[i].aw=result.e_v.e_con;
121 else if (result.e_typ==EV_STR)
122 token->t_att[i].as= result.e_v.e_str;
124 token->t_att[i].ar=result.e_v.e_reg;
130 cinstance(instno,token,tp,regno) register token_p token,tp; {
135 int sh; /* saved stackheight */
138 inp= &tokeninstances[instno];
139 switch(inp->in_which) {
143 assert(inp->in_info[0] == 1);
144 if (inp->in_info[1]==0) {
149 if (tp->t_token == -1) {
150 rp = &machregs[tp->t_att[0].ar];
151 token->t_att[0].ar=rp->r_members[inp->in_info[1]-1];
154 assert(tokens[tp->t_token].t_type[inp->in_info[1]-1] == EV_REG);
155 token->t_att[0].ar=tp->t_att[inp->in_info[1]-1].ar;
163 token->t_att[0].ar= inp->in_info[0];
167 assert(inp->in_info[0]==0);
170 regno=machregs[regno].r_members[inp->in_info[1]-1];
172 token->t_att[0].ar = regno;
176 stackheight = tp - fakestack + 1;
177 token->t_token=inp->in_info[0];
178 for (i=0;i<TOKENSIZE;i++)
179 if (inp->in_info[i+1]==0) {
180 assert(tokens[token->t_token].t_type[i]==0);
181 token->t_att[i].aw=0;
183 result=compute(&enodes[inp->in_info[i+1]]);
184 assert(tokens[token->t_token].t_type[i]==result.e_typ);
185 if (result.e_typ==EV_INT)
186 token->t_att[i].aw=result.e_v.e_con;
187 else if (result.e_typ==EV_STR)
188 token->t_att[i].as= result.e_v.e_str;
190 token->t_att[i].ar=result.e_v.e_reg;
197 eqtoken(tp1,tp2) token_p tp1,tp2; {
199 register tkdef_p tdp;
201 if (tp1->t_token!=tp2->t_token)
205 if (tp1->t_token==-1) {
206 if (tp1->t_att[0].ar!=tp2->t_att[0].ar)
210 tdp = &tokens[tp1->t_token];
211 for (i=0;i<TOKENSIZE;i++)
212 switch(tdp->t_type[i]) {
216 if (tp1->t_att[i].aw != tp2->t_att[i].aw)
220 if (tp1->t_att[i].ar != tp2->t_att[i].ar)
224 if (strcmp(tp1->t_att[i].as, tp2->t_att[i].as))
236 int expsize,toksize,exact;
239 bp = &coderules[cindex];
240 switch( (*bp)&037 ) {
242 return(stackheight==0 ? 0 : 100);
251 tpl= ((*bp++)>>5)&07;
252 if (stackheight < tpl) {
257 if (stackheight != tpl && xsekt==2)
260 tp= &fakestack[stackheight-1];
261 for (i=0;i<tpl;i++,tp--) {
263 if (!match(tp, &machsets[tokexp], 0)) {
266 expsize = ssize(tokexp);
283 unsigned costcalc(cost) cost_t cost; {
284 result_t result1,result2;
285 extern unsigned cc1,cc2,cc3,cc4;
287 result1=compute(&enodes[cost.c_size]);
288 result2=compute(&enodes[cost.c_time]);
289 assert(result1.e_typ == EV_INT && result2.e_typ == EV_INT);
290 return(result1.e_v.e_con*cc1/cc2 + result2.e_v.e_con*cc3/cc4);
295 return(machsets[tokexpno].set_size);
298 tsize(tp) register token_p tp; {
301 return(machregs[tp->t_att[0].ar].r_size);
302 return(tokens[tp->t_token].t_size);
306 instsize(tinstno,tp) token_p tp; {
310 inp = &tokeninstances[tinstno];
311 switch(inp->in_which) {
315 assert(inp->in_info[0]==1);
317 if (inp->in_info[1]==0)
322 assert(tp->t_token == -1);
323 rp = &machregs[tp->t_att[0].ar];
324 return(machregs[rp->r_members[inp->in_info[1]-1]].r_size);
328 return(machregs[inp->in_info[0]].r_size);
330 assert(FALSE); /* cannot occur in splitting coercion */
332 return(tokens[inp->in_info[0]].t_size);
335 #endif /* MAXSPLIT */
337 tref(tp,amount) register token_p tp; {
339 register tkdef_p tdp;
342 chrefcount(tp->t_att[0].ar,amount,FALSE);
344 tdp= &tokens[tp->t_token];
345 for(i=0;i<TOKENSIZE;i++)
346 if (tdp->t_type[i]==EV_REG)
347 chrefcount(tp->t_att[i].ar,amount,FALSE);
354 split(tp,ip,ply,toplevel) token_p tp; int *ip; {
356 token_t savestack[MAXSAVE];
363 for (cp=c2coercs;cp< &c2coercs[NC2]; cp++) {
364 if (!match(tp,&machsets[cp->c2_texpno],0))
367 for (i=0; ok && i<cp->c2_nsplit;i++) {
370 if (instsize(cp->c2_repl[i],tp) != ssize(ip[i]))
377 assert(stackheight+cp->c2_nsplit-1<MAXFSTACK);
378 stp = &fakestack[stackheight-1];
380 assert(diff<=MAXSAVE);
381 for (i=1;i<=diff;i++)
382 savestack[i-1] = tp[i]; /* save top of stack */
386 codegen(&coderules[cp->c2_codep],ply,toplevel,MAXINT,0);
388 for (i=0;i<diff;i++) /* restore top of stack */
389 fakestack[stackheight++] = savestack[i];
390 return(cp->c2_nsplit);
392 #endif /* MAXSPLIT */
394 unsigned docoerc(tp,cp,ply,toplevel,forced) token_p tp; c3_p cp; {
395 token_t savestack[MAXSAVE];
399 int tpl; /* saved tokpatlen */
401 stp = &fakestack[stackheight-1];
403 assert(diff<=MAXSAVE);
404 for (i=1;i<=diff;i++)
405 savestack[i-1] = tp[i];
409 cost = codegen(&coderules[cp->c3_codep],ply,toplevel,MAXINT,forced);
412 fakestack[stackheight++] = savestack[i];
417 unsigned stackupto(limit,ply,toplevel) token_p limit; {
418 token_t savestack[MAXFSTACK];
421 int tpl; /* saved tokpatlen */
422 int nareg; /* saved nareg */
426 unsigned totalcost=0;
427 struct reginfo *rp,**rpp;
429 for (tp=fakestack;tp<=limit;limit--) {
430 for (cp=c1coercs;cp< &c1coercs[NC1]; cp++) {
431 if (match(tp,&machsets[cp->c1_texpno],cp->c1_expr)) {
432 if (cp->c1_prop>=0) {
433 for (rpp=reglist[cp->c1_prop];
435 getrefcount((int)(rp-machregs), TRUE)!=0;
440 /* look for other possibility */
442 stp = &fakestack[stackheight-1];
444 assert(diff<=MAXFSTACK);
445 for (i=1;i<=diff;i++)
446 savestack[i-1] = tp[i];
451 for (i=0;i<nareg;i++)
453 if (cp->c1_prop>=0) {
454 nallreg=1; allreg[0] = rp-machregs;
455 chrefcount(allreg[0],1,FALSE);
458 totalcost+= codegen(&coderules[cp->c1_codep],ply,toplevel,MAXINT,0);
459 totalcost+= costcalc(cp->c1_cost);
462 fakestack[stackheight++] = savestack[i];
464 for (i=0;i<nareg;i++)
475 c3_p findcoerc(tp,tep) token_p tp; set_p tep; {
479 register struct reginfo **rpp;
481 for (cp=c3coercs;cp< &c3coercs[NC3]; cp++) {
482 if (tp!=(token_p) 0) {
483 if (!match(tp,&machsets[cp->c3_texpno],0))
486 if (cp->c3_texpno!=0)
489 if (cp->c3_prop==0) { /* no reg needed */
490 cinstance(cp->c3_repl,&rtoken,tp,0);
491 if (match(&rtoken,tep,0))
494 curreglist = (rl_p) myalloc(sizeof (rl_t));
495 curreglist->rl_n = 0;
496 for (rpp=reglist[cp->c3_prop];*rpp;rpp++) {
498 cinstance(cp->c3_repl,&rtoken,tp,i);
499 if (match(&rtoken,tep,0))
500 curreglist->rl_list[curreglist->rl_n++] = i;
502 if (curreglist->rl_n != 0)
507 return(0); /* nothing found */
511 error(s,a1,a2,a3,a4,a5,a6,a7,a8) char *s; {
513 fatal(s,a1,a2,a3,a4,a5,a6,a7,a8);
516 fatal(s,a1,a2,a3,a4,a5,a6,a7,a8) char *s; {
518 fprintf(stderr,"Error: ");
519 fprintf(stderr,s,a1,a2,a3,a4,a5,a6,a7,a8);
520 fprintf(stderr,"\n");
527 badassertion(asstr,file,line) char *asstr, *file; {
529 fatal("Assertion \"%s\" failed %s(%d)",asstr,file,line);