2 static char rcsid[] = "$Id: subr.c,v 0.19 1994/06/24 13:28:18 ceriel Exp $";
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
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;
32 if (tep->set_val[bitno>>4]&(1<<(bitno&017)))
33 if (tep->set_val[0]&1 || getrefcount(bitno, FALSE)<=1)
36 } else { /* token frame */
37 bitno = tp->t_token+NREGS;
38 if ((tep->set_val[bitno>>4]&(1<<(bitno&017)))==0)
46 compute(&enodes[optexp], &result);
48 return(result.e_v.e_con);
51 instance(instno,token) register token_p token; {
63 for (i=TOKENSIZE-1;i>=0;i--)
67 inp= &tokeninstances[instno];
68 switch(inp->in_which) {
72 if (inp->in_info[0] == 0)
73 if (curtoken) tp = curtoken;
74 else tp = &fakestack[stackheight-1];
75 else tp= &fakestack[stackheight-inp->in_info[0]];
76 if (inp->in_info[1]==0) {
81 assert(tp->t_token == -1);
82 rp = &machregs[tp->t_att[0].ar];
83 token->t_att[0].ar=rp->r_members[inp->in_info[1]-1];
90 if (inp->in_info[0] == 0)
91 if (curtoken) tp = curtoken;
92 else tp = &fakestack[stackheight-1];
93 else tp= &fakestack[stackheight-inp->in_info[0]];
94 assert(inp->in_info[1]!=0);
95 assert(tp->t_token>0);
97 assert(tokens[tp->t_token].t_type[inp->in_info[1]-1] == EV_REG);
98 token->t_att[0].ar=tp->t_att[inp->in_info[1]-1].ar;
102 token->t_att[0].ar= inp->in_info[0];
106 regno=allreg[inp->in_info[0]];
109 regno=machregs[regno].r_members[inp->in_info[1]-1];
111 token->t_att[0].ar = regno;
116 compute(&enodes[inp->in_info[1]], &result);
117 assert(result.e_typ==EV_INT);
118 if ((regno=isregvar(result.e_v.e_con)) > 0) {
120 token->t_att[0].ar = regno;
121 for (i=TOKENSIZE-1;i>0;i--)
122 token->t_att[i].aw = 0;
128 token->t_token=inp->in_info[0];
129 for (i=0;i<TOKENSIZE;i++)
130 if (inp->in_info[i+1]==0) {
131 assert(tokens[token->t_token].t_type[i]==0);
132 token->t_att[i].aw=0;
134 compute(&enodes[inp->in_info[i+1]], &result);
135 assert(tokens[token->t_token].t_type[i]==result.e_typ);
136 if (result.e_typ==EV_INT)
137 token->t_att[i].aw=result.e_v.e_con;
138 else if (result.e_typ==EV_ADDR)
139 token->t_att[i].aa= result.e_v.e_addr;
141 token->t_att[i].ar=result.e_v.e_reg;
147 cinstance(instno,token,tp,regno) register token_p token,tp; {
154 int sh; /* saved stackheight */
157 inp= &tokeninstances[instno];
158 switch(inp->in_which) {
162 assert(inp->in_info[0] <= 1);
163 if (inp->in_info[1]==0) {
168 assert(tp->t_token == -1);
169 rp = &machregs[tp->t_att[0].ar];
170 token->t_att[0].ar=rp->r_members[inp->in_info[1]-1];
177 assert(inp->in_info[0] <= 1);
179 assert(tp->t_token>0);
180 assert(tokens[tp->t_token].t_type[inp->in_info[1]-1] == EV_REG);
181 token->t_att[0].ar=tp->t_att[inp->in_info[1]-1].ar;
185 token->t_att[0].ar= inp->in_info[0];
189 assert(inp->in_info[0]==0);
192 regno=machregs[regno].r_members[inp->in_info[1]-1];
194 token->t_att[0].ar = regno;
199 { token_p ct = curtoken;
202 compute(&enodes[inp->in_info[1]], &result);
204 assert(result.e_typ==EV_INT);
205 if ((regno=isregvar(result.e_v.e_con)) > 0) {
207 token->t_att[0].ar = regno;
208 for (i=TOKENSIZE-1;i>0;i--)
209 token->t_att[i].aw = 0;
217 stackheight = tp - fakestack + 1;
218 token->t_token=inp->in_info[0];
219 for (i=0;i<TOKENSIZE;i++)
220 if (inp->in_info[i+1]==0) {
221 assert(tokens[token->t_token].t_type[i]==0);
222 token->t_att[i].aw=0;
224 token_p ct = curtoken;
227 compute(&enodes[inp->in_info[i+1]], &result);
229 assert(tokens[token->t_token].t_type[i]==result.e_typ);
230 if (result.e_typ==EV_INT)
231 token->t_att[i].aw=result.e_v.e_con;
232 else if (result.e_typ==EV_ADDR)
233 token->t_att[i].aa= result.e_v.e_addr;
235 token->t_att[i].ar=result.e_v.e_reg;
242 eqtoken(tp1,tp2) token_p tp1,tp2; {
244 register tkdef_p tdp;
246 if (tp1->t_token!=tp2->t_token)
250 if (tp1->t_token==-1) {
251 if (tp1->t_att[0].ar!=tp2->t_att[0].ar)
255 tdp = &tokens[tp1->t_token];
256 for (i=0;i<TOKENSIZE;i++)
257 switch(tdp->t_type[i]) {
261 if (tp1->t_att[i].aw != tp2->t_att[i].aw)
265 if (tp1->t_att[i].ar != tp2->t_att[i].ar)
269 if (strcmp(tp1->t_att[i].aa.ea_str, tp2->t_att[i].aa.ea_str))
271 if (tp1->t_att[i].aa.ea_off!=tp2->t_att[i].aa.ea_off)
283 int expsize,toksize,exact;
285 int fromstackneeded=0;
287 bp = &coderules[cindex];
294 switch( (*bp)&037 ) {
296 return(stackheight==0 ? 0 : 100);
305 tpl= ((*bp++)>>5)&07;
306 if (stackheight < tpl) {
309 fromstackneeded = tpl - stackheight;
312 if (stackheight != tpl && xsekt==2)
315 tp= &fakestack[stackheight-1];
316 for (i=0;i<tpl;i++,tp--) {
318 if (!match(tp, &machsets[tokexp], 0)) {
321 expsize = ssize(tokexp);
328 /* Now we have a match in size, but it is not exact.
329 Therefore, make sure that we can at least
330 create it from the stack!
332 if (! from_stack(&machsets[tokexp])) {
338 for (;i<tpl+fromstackneeded;i++) {
339 /* Make sure that any pattern we pick can be
343 if (! from_stack(&machsets[tokexp])) {
347 if (exact==tpl && ! fromstackneeded) {
352 return(20-2*exact+fromstackneeded);
355 extern set_t unstackset;
360 register set_p s2 = &unstackset;
362 for (i = 0; i < SETSIZE; i++) {
363 if ((s1->set_val[i] & s2->set_val[i]) != 0) return 1;
368 unsigned costcalc(cost) cost_t cost; {
369 extern unsigned cc1,cc2,cc3,cc4;
371 return(cost.ct_space*cc1/cc2 + cost.ct_time*cc3/cc4);
376 return(machsets[tokexpno].set_size);
379 tsize(tp) register token_p tp; {
382 return(machregs[tp->t_att[0].ar].r_size);
383 return(tokens[tp->t_token].t_size);
387 instsize(tinstno,tp) token_p tp; {
391 inp = &tokeninstances[tinstno];
392 switch(inp->in_which) {
396 assert(inp->in_info[0]<=1);
398 if (inp->in_info[1]==0)
403 assert(tp->t_token == -1);
404 rp = &machregs[tp->t_att[0].ar];
405 return(machregs[rp->r_members[inp->in_info[1]-1]].r_size);
409 return(machregs[inp->in_info[0]].r_size);
411 assert(FALSE); /* cannot occur in splitting coercion */
415 return(tokens[inp->in_info[0]].t_size);
418 #endif /* MAXSPLIT */
420 tref(tp,amount) register token_p tp; {
425 chrefcount(tp->t_att[0].ar,amount,FALSE);
427 tdpb= &tokens[tp->t_token].t_type[0];
428 for(i=0;i<TOKENSIZE;i++)
430 chrefcount(tp->t_att[i].ar,amount,FALSE);
435 /* A few routines to save the top of the current stack,
436 restore it and check whether a certain register is present in the
439 token_t aside[MAXSAVE] ;
440 int aside_length = -1 ;
442 save_stack(tp) register token_p tp ; {
444 token_p tmp = &fakestack[stackheight - 1];
446 /*aside_length = &fakestack[stackheight-1] -tp;
447 This did not compile on Xenix V3.2: CODE GENERATION ERROR!
449 aside_length = tmp - tp;
450 assert(aside_length<=MAXSAVE);
452 if (aside_length!=0 && Debug>1)
453 fprintf(stderr,"Saving %d items from fakestack\n",aside_length);
455 for (i=1;i<=aside_length;i++)
457 stackheight -= aside_length;
461 register token_p tp ;
463 register tkdef_p tdp ;
465 for ( i=0, tp=aside ; i<aside_length ; i++, tp++ )
466 if (tp->t_token==-1) {
467 if(tp->t_att[0].ar==reg)
470 tdp = &tokens[tp->t_token];
471 for(i=0;i<TOKENSIZE;i++)
472 if (tdp->t_type[i]==EV_REG &&
473 tp->t_att[i].ar==reg)
480 fprintf(stderr,"Register %d present on non-visible stack\n",
489 assert(aside_length!= -1);
491 if (aside_length!=0 && Debug>1)
492 fprintf(stderr,"Restoring %d items to fakestack(%d)\n",
493 aside_length,stackheight);
495 for (i=0;i<aside_length;i++)
496 fakestack[stackheight++] = aside[i];
501 split(tp,ip,ply,toplevel) token_p tp; register int *ip; {
503 token_t savestack[MAXSAVE];
510 for (cp=c2coercs;cp->c2_texpno>=0; cp++) {
511 if (!match(tp,&machsets[cp->c2_texpno],0))
514 for (i=0; ok && i<cp->c2_nsplit;i++) {
517 if (instsize(cp->c2_repl[i],tp) != ssize(ip[i]))
524 assert(stackheight+cp->c2_nsplit-1<MAXFSTACK);
528 codegen(&coderules[cp->c2_codep],ply,toplevel,MAXINT,0);
531 return(cp->c2_nsplit);
533 #endif /* MAXSPLIT */
535 unsigned docoerc(tp,cp,ply,toplevel,forced) token_p tp; register c3_p cp; {
537 int tpl; /* saved tokpatlen */
542 cost = codegen(&coderules[cp->c3_codep],ply,toplevel,MAXINT,forced);
549 unsigned stackupto(limit,ply,toplevel) token_p limit; {
550 token_t savestack[MAXFSTACK];
553 int tpl; /* saved tokpatlen */
554 int nareg; /* saved nareg */
558 unsigned totalcost=0;
559 struct reginfo *rp,**rpp;
561 for (tp=fakestack;tp<=limit;limit--) {
562 for (cp=c1coercs;cp->c1_texpno>=0; cp++) {
563 if (match(tp,&machsets[cp->c1_texpno],cp->c1_expr)) {
564 if (cp->c1_prop>=0) {
565 for (rpp=reglist[cp->c1_prop];
567 getrefcount((int)(rp-machregs), TRUE)!=0;
572 /* look for other possibility */
574 stp = &fakestack[stackheight-1];
576 assert(diff<=MAXFSTACK);
577 for (i=1;i<=diff;i++)
578 savestack[i-1] = tp[i];
583 for (i=0;i<nareg;i++)
585 if (cp->c1_prop>=0) {
586 nallreg=1; allreg[0] = rp-machregs;
587 chrefcount(allreg[0],1,FALSE);
590 totalcost+= codegen(&coderules[cp->c1_codep],ply,toplevel,MAXINT,0);
592 for (i=0;i<diff;i++) {
593 fakestack[stackheight] = savestack[i];
595 /* not cobmined in one statement;
596 this poor Xenix C compiler sometimes
597 gets failed assertions when you do
602 for (i=0;i<nareg;i++)
613 c3_p findcoerc(tp,tep) token_p tp; set_p tep; {
617 register struct reginfo **rpp;
619 for (cp=c3coercs;cp->c3_texpno>=0; cp++) {
620 if (tp!=(token_p) 0) {
621 if (cp->c3_texpno==0)
623 if (!match(tp,&machsets[cp->c3_texpno],cp->c3_expr))
626 if (cp->c3_texpno!=0)
629 if (cp->c3_prop<0) { /* no reg needed */
630 cinstance(cp->c3_repl,&rtoken,tp,0);
631 if (match(&rtoken,tep,0))
634 curreglist = (rl_p) myalloc(sizeof (rl_t));
635 curreglist->rl_n = 0;
636 for (rpp=reglist[cp->c3_prop];*rpp;rpp++) {
638 cinstance(cp->c3_repl,&rtoken,tp,i);
639 if (match(&rtoken,tep,0))
640 curreglist->rl_list[curreglist->rl_n++] = i;
642 if (curreglist->rl_n != 0)
644 myfree((string)curreglist);
647 return(0); /* nothing found */
651 register tkdef_p tdp;
653 for(tdp=tokens+1;tdp->t_size!=0;tdp++)
654 tdp->t_cost.ct_space = costcalc(tdp->t_cost);
658 error(s,a1,a2,a3,a4,a5,a6,a7,a8) char *s; {
660 fprintf(stderr,"Error: ");
661 fprintf(stderr,s,a1,a2,a3,a4,a5,a6,a7,a8);
662 fprintf(stderr,"\n");
671 fatal(s,a1,a2,a3,a4,a5,a6,a7,a8) char *s; {
673 fprintf(stderr,"Fatal: ");
674 fprintf(stderr,s,a1,a2,a3,a4,a5,a6,a7,a8);
675 fprintf(stderr,"\n");
688 extern int tablelines[MAXTDBUG];
689 extern int ntableline;
690 extern char *tablename;
692 fprintf(stderr,"Last code rules used\n");
694 while(i!=ntableline) {
697 if (tablelines[i]!=0)
698 fprintf(stderr,"\%d: \"%s\", line %d\n",i,tablename,tablelines[i]);
705 badassertion(asstr,file,line) char *asstr, *file; {
707 fatal("\"%s\", line %d:Assertion \"%s\" failed",file,line,asstr);