Pristine Ack-5.5
[Ack-5.5.git] / util / ncgg / output.c
1 /*
2  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
3  * See the copyright notice in the ACK home directory, in the file "Copyright".
4  */
5 /* #define CODEDEBUG    /* print readable code */
6 #ifdef CODEDEBUG
7 int     code_in_c=0;    /* put readable code in "code" */
8 int     tabledebug=1;   /* generate code for table debugging */
9 #else
10 int     code_in_c=1;    /* put code in "tables.c" */
11 int     tabledebug=0;   /* do not generate code for table debugging */
12 #endif
13 int     verbose=0;      /* print all statistics */
14 int     use_tes;        /* use top element size information */
15 char    *c_file=        "tables.c";
16 char    *h_file=        "tables.H";
17 char    *cd_file=       "code";
18
19 #ifndef NORCSID
20 static char rcsid[]= "$Id: output.c,v 0.26 1994/06/24 10:37:52 ceriel Exp $";
21 #endif
22
23 #include <stdio.h>
24 #include <ctype.h>
25 #include "assert.h"
26 #include "varinfo.h"
27 #include "param.h"
28 #include "reg.h"
29 #include "property.h"
30 #include "token.h"
31 #include "set.h"
32 #include "instruct.h"
33 #include "lookup.h"
34 #include <cgg_cg.h>
35 #include "pseudo.h"
36 #include "regvar.h"
37 #include "extern.h"
38
39 #define BMASK 0xFF
40 #define BSHIFT 8
41
42 FILE *ctable,*htable;
43 FILE *code;
44 short *lineset;
45 int maxline;
46
47 extern int nstrings;
48 extern char *l_strings[];
49
50 extern int ninstances;
51 extern inst_t l_instances[];
52
53 extern int nmoves;
54 extern move_t l_moves[];
55 extern int ntests;
56 extern test_t l_tests[];
57 extern int nstacks;
58 extern c1_t l_stacks[];
59 extern int ncoercs;
60 extern c3_t l_coercs[];
61 extern int nsplit,maxsplit;
62 extern c2_t l_split[];
63 extern set_t l_sets[];
64
65 int maxallreg=0;
66 int maxregvars=0;
67 int setsize;
68
69 opnfile(f,s) FILE **f; char *s; {
70
71         if ((*f=fopen(s,"w"))==NULL)
72                 fatal("Can't create %s",s);
73 }
74
75 unlfile(f,s) FILE *f; char *s; {
76
77         if (f) fclose(f);
78         if (unlink(s)<0)
79                 error("%s incorrect, must be removed!!",s);
80 }
81
82 initio() {
83         extern char *myalloc();
84
85         opnfile(&ctable,c_file);
86         opnfile(&htable,h_file);
87         if (code_in_c)
88                 fprintf(ctable,"char coderules[] = {");
89         else
90                 opnfile(&code,cd_file);
91         patbyte(0);
92         if (tabledebug)
93                 lineset = (short *) myalloc(SZOFSET(MAXSOURCELINES)*sizeof(short));
94 }
95
96 finishcode() {
97
98         if (code_in_c)
99                 fprintf(ctable,"\n};\n\n");
100         fprintf(ctable, "int allsetno = %d;\n", allsetno);
101         if (tabledebug) {
102                 int fd;
103                 int sz;
104                 
105                 if ((fd=creat("lineset",0666))>=0) {
106                         sz = SZOFSET(maxline)*2;
107                         write(fd,&sz,sizeof(int));
108                         write(fd,lineset,sz);
109                         close(fd);
110                 } else
111                         error("Can't create lineset");
112         }
113 }
114
115 errorexit() {
116
117         unlfile(ctable,c_file);
118         unlfile(htable,h_file);
119         if (!code_in_c)
120                 unlfile(code,cd_file);
121 }
122
123 #ifdef CODEDEBUG
124 #define code8(x) fprintf(code,"%s","x")
125 #define code8nl(x) fprintf(code,"%s\n","x")
126 #define code53(x,y) fprintf(code,"%s-%d","x",y)
127 #define codeint(x) fprintf(code," %d",x)
128 #define codenl() fprintf(code,"\n")
129 #else
130 #define codenl()
131 #define code8nl(x) code8(x)
132
133 code8(x) {
134
135         codeindex++;
136         if (code_in_c)
137                 fprintf(ctable,"%d,",x&0377);
138         else
139                 putc(x,code);
140 }
141
142 code53(x,y) {
143
144         code8(x+(y<<5));
145 }
146
147 codeint(x) {
148
149         assert(x>=0 && x<=32767);
150         if (x<128) {
151                 code8(x);
152         } else {
153                 code8(x/256+128);
154                 code8(x%256);
155         }
156 }
157
158 #endif
159 int prevind=0;
160 int npatbytes= -1;
161 char pattern[MAXPATBYTES];
162 int pathash[256];
163
164 outpatterns() {
165         extern int npatterns;
166         extern int patindex[];
167         extern int empatlen;
168         extern int emmnem[];
169         extern int empatexpr;
170         register i;
171
172         if (!inproc) {
173                 patbyte(0);
174                 patshort(prevind);
175                 prevind = npatbytes-2;
176                 patbyte(empatlen);
177                 for(i=0;i<empatlen;i++)
178                         patbyte(emmnem[i]);
179                 pat(empatexpr);
180         }
181         if (callproc==0) {
182                 patbyte(npatterns);
183                 for(i=0;i<npatterns;i++)
184                         pat(patindex[i]);
185         } else {
186                 patbyte(0);
187                 pat(callproc);
188                 pat(nprocargs);
189                 for (i = 0; i < nprocargs; i++) pat(procarg[i]);
190         }
191 }
192
193 pat(n) {
194
195         assert(n>=0);
196         if (n<128)
197                 patbyte(n);
198         else {
199                 patbyte(n/256+128);
200                 patbyte(n%256);
201         }
202 }
203
204 patshort(n) {
205
206         patbyte(n%256);
207         patbyte(n/256);
208 }
209
210 patbyte(n) {
211
212         NEXT(npatbytes, MAXPATBYTES, "Pattern bytes");
213         pattern[npatbytes]=n;
214 }
215
216 hashpatterns() {
217         short index;
218         register char *bp,*tp;
219         register short i;
220         unsigned short hashvalue;
221         int patlen;
222
223         index = prevind;
224         while (index != 0) {
225                 bp = &pattern[index];
226                 tp = &bp[PO_MATCH];
227                 i = *tp++&BMASK;
228                 if (i==BMASK) {
229                         i = *tp++&BMASK;
230                         i |= (*tp++&BMASK)<<BSHIFT;
231                 }
232                 patlen = i;
233                 hashvalue = 0;
234                 switch(patlen) {
235                 default:        /* 3 or more */
236                         hashvalue = (hashvalue<<4)^(*tp++&BMASK);
237                 case 2:
238                         hashvalue = (hashvalue<<4)^(*tp++&BMASK);
239                 case 1:
240                         hashvalue = (hashvalue<<4)^(*tp++&BMASK);
241                 }
242                 assert(hashvalue!= ILLHASH);
243                 i=index;
244                 index = (bp[PO_NEXT]&BMASK)|(bp[PO_NEXT+1]<<BSHIFT);
245                 bp[PO_HASH] = hashvalue>>BSHIFT;
246                 hashvalue &= BMASK;
247                 bp[PO_NEXT] = pathash[hashvalue]&BMASK;
248                 bp[PO_NEXT+1] = pathash[hashvalue]>>BSHIFT;
249                 pathash[hashvalue] = i;
250         }
251 }
252
253 outincludes() {
254
255         fprintf(ctable,"#include \"param.h\"\n");
256         fprintf(ctable,"#include \"tables.h\"\n");
257         fprintf(ctable,"#include \"types.h\"\n");
258         fprintf(ctable,"#include <cgg_cg.h>\n");
259         fprintf(ctable,"#include \"data.h\"\n");
260 }
261
262 outregs() {
263         register i,j,k;
264         short rset[SZOFSET(MAXREGS)];
265         short clashlist[MAXREGS*MAXREGS];
266         int iclashlist = 0;
267         int t,ready;
268
269
270         fprintf(ctable,"char stregclass[] = {\n");
271         for (i=0;i<nregs;i++)
272                 fprintf(ctable,"\t%d,\n",l_regs[i].ri_class);
273         fprintf(ctable,"};\n\nstruct reginfo machregs[] = {\n{0},\n");
274         for (i=1;i<nregs;i++) {
275                 fprintf(ctable,"{%d,%d",strlookup(l_regs[i].ri_repr),
276                         l_regs[i].ri_size);
277                 if (maxmembers!=0) {
278                         fprintf(ctable,",{");
279                         for(j=0;j<maxmembers;j++)
280                                 fprintf(ctable,"%d,",l_regs[i].ri_memb[j]);
281                         /* now compute and print set of registers
282                          * that clashes with this register.
283                          * A register clashes with al its children (and theirs)
284                          * and with all their parents.
285                          */
286                         for (j=0;j<SZOFSET(MAXREGS);j++)
287                                 rset[j]=0;
288                         BIS(rset,i);
289                         do {
290                             ready=1;
291                             for (j=1;j<nregs;j++)
292                                 if (BIT(rset,j))
293                                     for (k=0;k<2;k++)
294                                         if ((t=l_regs[j].ri_memb[k])!=0) {
295                                             if (BIT(rset,t)==0)
296                                                 ready=0;
297                                             BIS(rset,t);
298                                         }
299                         } while (!ready);
300                         do {
301                             ready=1;
302                             for (j=1;j<nregs;j++)
303                                 for (k=0;k<2;k++)
304                                     if ((t=l_regs[j].ri_memb[k])!=0)
305                                         if (BIT(rset,t)) {
306                                                 if (BIT(rset,j)==0)
307                                                     ready=0;
308                                                 BIS(rset,j);
309                                         }
310                         } while (!ready);
311                         fprintf(ctable,"},{");
312                         for (j=0;j<SZOFSET(nregs);j++)
313                                 fprintf(ctable,"0%o,",rset[j]&0xFFFF);
314                         fprintf(ctable,"}, %d", iclashlist);
315                         for (j = 1; j < nregs; j++) {
316                                 if (BIT(rset, j)) clashlist[iclashlist++] = j;
317                         }
318                         clashlist[iclashlist++] = 0;
319                 }
320                 fprintf(ctable,",%d",l_regs[i].ri_rregvar>=0);
321                 fprintf(ctable,"},\n");
322         }
323         fprintf(ctable,"};\n\n short clashlist[] = {\n\t");
324         for (i = 0; i < iclashlist; i++) {
325                 fprintf(ctable, "%d, ", clashlist[i]);
326                 if (clashlist[i] == 0) fprintf(ctable, "\n\t");
327         }
328         fprintf(ctable, "0};\n\n");
329 }
330
331 outregvars() {
332         register i,j;
333
334         fprintf(htable,"#define REGVARS\n");
335         fprintf(ctable,"#include \"regvar.h\"\n");
336         fprintf(ctable,"int nregvar[4] = { ");
337         for (i=0;i<4;i++) {
338                 fprintf(ctable,"%d, ",nregvar[i]);
339                 if (nregvar[i]>maxregvars)
340                         maxregvars = nregvar[i];
341         }
342         fprintf(ctable,"};\n");
343         for (i=0;i<4;i++)
344                 if (nregvar[i]>0)
345                         fprintf(ctable,"struct regassigned ratar%d[%d];\n",
346                                         i,nregvar[i]);
347         for (i=0;i<4;i++) if (nregvar[i]>0) {
348                 fprintf(ctable,"int rvtar%d[] = {",i);
349                 for (j=0;j<nregvar[i];j++)
350                         fprintf(ctable,"%d,",rvnumbers[i][j]);
351                 fprintf(ctable,"};\n");
352         }
353         fprintf(ctable,"\nint *rvnumbers[] = {\n");
354         for (i=0;i<4;i++)
355                 if (nregvar[i]>0)
356                         fprintf(ctable,"\trvtar%d,\n",i);
357                 else
358                         fprintf(ctable,"\t0,\n");
359         fprintf(ctable,"};\n\nstruct regassigned *regassigned[] = {\n");
360         for (i=0;i<4;i++)
361                 if (nregvar[i]>0)
362                         fprintf(ctable,"\tratar%d,\n",i);
363                 else
364                         fprintf(ctable,"\t0,\n");
365         fprintf(ctable,"};\n");
366 }
367
368 typeconv(n) {
369
370         if (n>=0) return(2);
371         if (n== -1) return(1);
372         if (n== -2) return(3);
373         assert (n== -3);
374         return(0);
375 }
376
377 outfmt(p)
378 register char *p;
379 {
380         register int c;
381         fprintf(ctable,"\"");
382         while ((c= (*p++&0377))!=0) {
383                 if (! isascii(c) || iscntrl(c)) {
384                         fprintf(ctable,"\\%c%c%c",
385                                 ((c&~0300)>>6) + '0', ((c&070)>>3)+'0',
386                                 (c&07)+'0');
387                 }
388                 else fprintf(ctable, "%c",c);
389         }
390         fprintf(ctable,"\"");
391 }
392
393 outtokens() {
394         register tokno,i;
395         register token_p tp;
396
397         fprintf(ctable,"tkdef_t tokens[] = {{0},\n");
398         for (tokno=1;tokno<ntokens;tokno++) {
399                 tp = l_tokens[tokno];
400                 fprintf(ctable,"/* %3d */{%d,{%d,%d},{", tokno,
401                         tp->tk_size, tp->tk_cost.ct_space, tp->tk_cost.ct_time);
402                 for(i=0;i<maxtokensize;i++)
403                         fprintf(ctable,"%d,",typeconv(tp->tk_att[i].ta_type));
404                 fprintf(ctable,"},%d},\t/* ",tp->tk_format);
405                 if (tp->tk_format >= 0) outfmt(l_strings[tp->tk_format]);
406                 else fprintf(ctable, "(no format)");
407                 fprintf(ctable," */\n");
408         }
409         fprintf(ctable,"{0}};\n\n");
410 }
411
412 outenodes() {
413         register node_p np;
414         extern node_t nodes[];
415         extern int nnodes;
416
417         fprintf(ctable,"node_t enodes[] = {\n");
418         for (np=nodes;np<&nodes[nnodes];np++)
419                 fprintf(ctable,"{%d,%d,%d},\n",
420                         np->ex_operator,np->ex_lnode,np->ex_rnode);
421         fprintf(ctable,"};\n\n");
422 }
423
424 outstrings() {
425         register i;
426         register char *p;
427         register int c;
428         extern char * filename;
429
430         if (tabledebug)
431                 fprintf(ctable,"char *tablename = \"%s\";\n",filename);
432         fprintf(ctable,"string codestrings[] = {\n");
433         for(i=0;i<nstrings;i++) {
434                 fprintf(ctable,"\t");
435                 outfmt(l_strings[i]);
436 #if 0
437                 while ((c= (*p++&0377))!=0) {
438                         if (! isascii(c) || iscntrl(c)) {
439                                 fprintf(ctable,"\\%c%c%c",
440                                         ((c&~0300)>>6) + '0', ((c&070)>>3)+'0',
441                                         (c&07)+'0');
442                         }
443                         else fprintf(ctable, "%c",c);
444                 }
445                 fprintf(ctable,"\",\n");
446 #endif
447                 fprintf(ctable,",\n");
448         }
449         fprintf(ctable,"};\n\n");
450 }
451
452 extern set_t unstackset;
453
454 outsets() {
455         register i;
456         register set_p sp;
457
458         fprintf(ctable,"set_t machsets[] = {\n");
459         for (sp=l_sets;sp< &l_sets[nsets]; sp++) {
460                 fprintf(ctable,"/* %3ld */ {%3d,{",(long)(sp-l_sets),sp->set_size);
461                 for (i=0;i<setsize;i++)
462                         fprintf(ctable,"0x%x,",sp->set_val[i]&0xFFFF);
463                 fprintf(ctable,"}},\n");
464         }
465         fprintf(ctable,"};\n\n");
466
467         fprintf(ctable, "set_t unstackset = { %3d,{\n", unstackset.set_size);
468         for (i = 0; i<setsize;i++)
469                 fprintf(ctable,"0x%x,",unstackset.set_val[i]&0xFFFF);
470         fprintf(ctable,"}};\n\n");
471 }
472
473 outinstances() {
474         register inst_p ip;
475         register i;
476
477         fprintf(ctable,"inst_t tokeninstances[] = {\n");
478         for (ip=l_instances;ip< &l_instances[ninstances]; ip++) {
479                 fprintf(ctable,"{ %d, {",ip->in_which);
480                 for(i=0;i<=maxtokensize;i++)
481                         fprintf(ctable,"%d,",ip->in_info[i]);
482                 fprintf(ctable,"}},\n");
483         }
484         fprintf(ctable,"};\n\n");
485 }
486
487 outmoves() {
488         register move_p mp;
489
490         fprintf(ctable,"move_t moves[] = {\n");
491         for (mp=l_moves; mp< &l_moves[nmoves]; mp++)
492                 fprintf(ctable,"{%d,%d,%d,%d,%d},\n",
493                         mp->m_set1, mp->m_expr1,
494                         mp->m_set2, mp->m_expr2,
495                         mp->m_cindex);
496         fprintf(ctable,"{-1}\n};\n\n");
497 }
498
499 outtests() {
500         register test_p tp;
501
502         fprintf(ctable,"test_t tests[] = {\n");
503         for (tp=l_tests; tp< &l_tests[ntests]; tp++)
504                 fprintf(ctable,"{%d,%d,%d},\n",
505                         tp->t_set, tp->t_expr,
506                         tp->t_cindex);
507         fprintf(ctable,"{-1}\n};\n\n");
508 }
509
510 outstacks() {
511         register c1_p cp;
512
513         fprintf(ctable,"c1_t c1coercs[] = {\n");
514         for (cp=l_stacks; cp< &l_stacks[nstacks]; cp++)
515                 fprintf(ctable,"{%d,%d,%d,%d},\n",
516                         cp->c1_texpno, cp->c1_expr,
517                         cp->c1_prop, cp->c1_codep);
518         fprintf(ctable,"{-1}\n};\n\n");
519 }
520
521 outsplits() {
522         register c2_p cp;
523         register i;
524
525         fprintf(ctable,"c2_t c2coercs[] = {\n");
526         for (cp=l_split; cp< &l_split[nsplit]; cp++) {
527                 fprintf(ctable,"{%d,%d,%d,{",
528                         cp->c2_texpno, cp->c2_expr, cp->c2_nsplit);
529                 for (i=0;i<maxsplit;i++)
530                         fprintf(ctable,"%d,",cp->c2_repl[i]);
531                 fprintf(ctable,"},%d},\n",cp->c2_codep);
532         }
533         fprintf(ctable,"{-1}\n};\n\n");
534 }
535
536 outcoercs() {
537         register c3_p cp;
538
539         fprintf(ctable,"c3_t c3coercs[] = {\n");
540         for (cp=l_coercs; cp< &l_coercs[ncoercs]; cp++)
541                 fprintf(ctable,"{%d,%d,%d,%d,%d},\n",
542                         cp->c3_texpno, cp->c3_expr,
543                         cp->c3_prop, cp->c3_repl, cp->c3_codep);
544         fprintf(ctable,"{-1}\n};\n\n");
545 }
546
547 outproplists() {
548         register propno;
549         register regno;
550
551         for(propno=0;propno<nprops;propno++) {
552                 fprintf(ctable,"struct reginfo *rlist%d[] = {\n",propno);
553                 for(regno=1;regno<nregs;regno++)
554                         if (BIT(l_props[propno].pr_regset,regno))
555                                 fprintf(ctable,"&machregs[%d],\n",regno);
556                 fprintf(ctable,"0\n};\n");
557         }
558         fprintf(ctable,"struct reginfo **reglist[] = {\n");
559         for(propno=0;propno<nprops;propno++)
560                 fprintf(ctable,"rlist%d,\n",propno);
561         fprintf(ctable,"};\n\n");
562 }
563
564 outconsts() {
565
566         fprintf(ctable,"unsigned cc1 = %u;\n",fc1);
567         fprintf(ctable,"unsigned cc2 = %u;\n",fc2);
568         fprintf(ctable,"unsigned cc3 = %u;\n",fc3);
569         fprintf(ctable,"unsigned cc4 = %u;\n",fc4);
570 }
571
572 cdef(s,n) char *s; {
573
574         fprintf(htable,"#define %s %d\n",s,n);
575 }
576
577 passon(s) char *s; {
578         char buf[32];
579
580         sprintf(buf,"T%s",s);
581         cdef(buf,cmustbeset(s));
582 }
583
584 outdefs() {
585         register symbol *sy_p;
586         extern int maxempatlen,maxrule;
587         char *wrdfmt;
588
589         passon("EM_WSIZE");
590         passon("EM_PSIZE");
591         passon("EM_BSIZE");
592         if ((sy_p=lookup("FORMAT",symsconst,justlooking))!=0) {
593                 wrdfmt = l_strings[sy_p->sy_value.syv_stringno];
594                 fprintf(htable,"#define WRD_FMT \"%s\"\n",wrdfmt);
595         }
596         cdef("MAXALLREG",maxallreg);
597         cdef("SETSIZE",setsize);
598         cdef("NREGS",nregs);
599         cdef("REGSETSIZE",SZOFSET(nregs));
600         cdef("TOKENSIZE",maxtokensize);
601         cdef("MAXMEMBERS",maxmembers);
602         cdef("LONGESTPATTERN",maxempatlen);
603         cdef("MAXPATLEN",maxtokpatlen);
604         cdef("MAXREPLLEN",maxtokrepllen);
605         cdef("MAXEMREPLLEN",maxemrepllen);
606         cdef("MAXPROCARG",maxprocargs);
607         cdef("MAXRULE",maxrule<16 ? 16 : maxrule);
608         if (nsplit>0) {
609                 cdef("MAXSPLIT",maxsplit);
610         }
611         if (tabledebug)
612                 cdef("TABLEDEBUG",1);
613         if (use_tes)
614                 cdef("USE_TES",1);
615 }
616
617 outars() {
618         register i;
619         
620         if (code_in_c)
621                 fprintf(htable,"#define CODEINC 1\n");
622         else {
623                 fprintf(ctable,"char coderules[%d];\n",codeindex);
624                 fprintf(ctable,"int ncodebytes=%d;\n",codeindex);
625         }
626         fprintf(ctable,"char pattern[%d]={\n",npatbytes+1);
627         for(i=0;i<=npatbytes;i++) {
628                 fprintf(ctable,"%d,%c",pattern[i]&BMASK,i%16==15 ? '\n' : ' ');
629         }
630         fprintf(ctable,"};\n\n");
631         fprintf(ctable,"int pathash[256]={\n");
632         for(i=0;i<256;i++) {
633                 fprintf(ctable,"%d,%c",pathash[i]&0xFFFF,i%10==9 ? '\n' : ' ');
634         }
635         fprintf(ctable,"};\n");
636 }
637
638 finishio() {
639         extern int nregs;
640
641         finishcode();
642         hashpatterns();
643         setsize = SZOFSET(nregs+ntokens);
644         outdefs();
645         outincludes();
646         outregs();
647         outtokens();
648         outenodes();
649         outstrings();
650         outsets();
651         outinstances();
652         outmoves();
653         outtests();
654         outstacks();
655         if (nsplit>0)
656                 outsplits();
657         outcoercs();
658         outproplists();
659         outconsts();
660         if (rvused)
661                 outregvars();
662         outars();
663 }
664
665 codecoco(cocono) {
666
667         if (cocono== -1)
668                 return;
669         code8(DO_SETCC);
670         codeint(cocono);
671         codenl();
672 }
673
674 dopattern(stackcoerc,kills,allocates,generates,yields,leaving)
675 varinfo *kills,*allocates,*generates,*yields,*leaving;
676 {
677         register i;
678         int n,nops;
679         register struct varinfo *vp,*vivp;
680         register instr_p instp;
681         int al,deal;
682         int vil;
683         int cocono= -1;
684         cost_t totcost;
685         int nremoves;
686         int removelist[100];
687         static char tlab[] = "0:";
688         extern int optexact,optstack,startline;
689         extern char *filename;
690         extern int lineno;
691
692 #ifdef CODEDEBUG
693         fprintf(code,"Code(%d) at \"%s\", line %d\n",stackcoerc,filename,lineno);
694 #endif
695         if (code_in_c)
696                 fprintf(ctable,"\n/* \"%s\", line %d */ ",filename,lineno);
697         if (tabledebug) {
698                 code8(DO_DLINE);
699                 codeint(startline); 
700                 codenl();
701                 if (startline<MAXSOURCELINES) {
702                         if (startline>maxline)
703                                 maxline=startline;
704                         BIS(lineset,startline);
705                 } else {
706                         static int beenhere=0;
707
708                         if (!beenhere) {
709                                 beenhere++;
710                                 error("Too many source lines for table debug");
711                         }
712                 }
713         }
714         /* MATCH part */
715         if (tokpatlen) {
716                 if (optexact)
717                         if (optstack)
718                                 code53(DO_XXMATCH,tokpatlen);
719                         else
720                                 code53(DO_XMATCH,tokpatlen);
721                 else
722                         code53(DO_MATCH,tokpatlen);
723                 for (i=0;i<tokpatlen;i++)
724                         codeint(tokpatset[i]);
725                 codenl();
726         } else if (stackcoerc)
727                 code8nl(DO_COERC);
728         if (optstack) {
729                 code53(DO_TOSTACK,0);
730                 codeint(allsetno);
731                 codenl();
732         }
733         /* The kills */
734         for (vp=kills;vp!=0;vp=vp->vi_next) {
735                 if (vp->vi_int[1] != 0) {
736                         code53(DO_REMOVE,1);
737                         codeint(vp->vi_int[0]);
738                         codeint(vp->vi_int[1]);
739                 } else if (vp->vi_int[0] >= 0) {
740                         code53(DO_REMOVE,0);
741                         codeint(vp->vi_int[0]);
742                 } else {
743                         code8(DO_KILLREG);
744                         codeint(-vp->vi_int[0] - 1);
745                 }
746                 codenl();
747         }
748         nremoves=0;
749         for(vp=generates;vp!=0;vp=vp->vi_next) {
750                 if (vp->vi_int[0] != INSREMOVE)
751                         continue;
752                 for(i=0;i<nremoves;i++)
753                         if (vp->vi_int[1]==removelist[i])
754                                 break;
755                 if (i==nremoves) {
756                         assert(nremoves<(sizeof(removelist)/sizeof(int)));
757                         removelist[nremoves++] = vp->vi_int[1];
758                 }
759         }
760         for(i=0;i<nremoves;i++) {
761                 code8(DO_RREMOVE);
762                 codeint(removelist[i]);
763                 codenl();
764         }
765         /* allocate part */
766         deal=0;al=0;
767         for (vp=allocates;vp!=0;vp=vp->vi_next) {
768                 if (vp->vi_int[0] == -1) { /* Deallocate */
769                         deal++;
770                         code8(DO_DEALLOCATE);
771                         codeint(vp->vi_int[1]);
772                         codenl();
773                 } else {
774                         if (vp->vi_int[1]==0) {
775                                 code53(DO_ALLOCATE,0);
776                                 codeint(vp->vi_int[0]);
777                                 codenl();
778                         } else {
779                                 code53(DO_ALLOCATE,1);
780                                 codeint(vp->vi_int[0]);
781                                 codeint(vp->vi_int[1]);
782                                 codenl();
783                         }
784                         al++;
785                 }
786         }
787         if (deal)
788                 code8nl(DO_REALLOCATE);
789         if (al>maxallreg)
790                 maxallreg=al;
791         totcost.ct_space = 0;
792         totcost.ct_time  = 0;
793         for(vp=generates;vp!=0;vp=vp->vi_next) {
794                 n= vp->vi_int[0];
795                 switch(n) {
796                 default:
797                         assert(n>=0);
798                         instp = &l_instr[n];
799                         nops=instp->i_nops;
800                         code53(DO_INSTR,nops);
801                         if (vp->vi_int[1]==0) {
802                                 codeint(instp->i_asname);
803                         } else {
804                                 codeint(10000+vp->vi_int[1]);
805                         }
806                         vivp=vp->vi_vi;
807                         for(i=0;i<nops;i++) {
808                                 codeint(vivp->vi_int[0]);
809                                 vivp = vivp->vi_vi;
810                         }
811                         codenl();
812                         totcost.ct_space += instp->i_cost.ct_space;
813                         totcost.ct_time  += instp->i_cost.ct_time ;
814                         break;
815                 case INSREMOVE:
816                         break;
817                 case INSMOVE:
818                         codecoco(cocono);
819                         code8(DO_MOVE);
820                         codeint(vp->vi_int[1]);
821                         codeint(vp->vi_int[2]);
822                         codenl();
823                         break;
824                 case INSTEST:
825                         codecoco(cocono);
826                         code8(DO_TEST);
827                         codeint(vp->vi_int[1]);
828                         codenl();
829                         break;
830                 case INSPRETURN:
831                         code8(DO_PRETURN);
832                         codenl();
833                         break;
834                 case INSTLAB:
835                         cocono = 0;
836                         tlab[0] = vp->vi_int[1] + '0';
837                         code53(DO_INSTR,0);
838                         codeint(strlookup(tlab));
839                         codenl();
840                         break;
841                 case INSSETCC:
842                         cocono=vp->vi_int[1];
843                         break;
844                 case INSERASE:
845                         code8(DO_ERASE);
846                         codeint(vp->vi_int[1]);
847                         codenl();
848                         break;
849                 case INSLABDEF:
850                         cocono = 0;
851                         code8(DO_LABDEF);
852                         codeint(vp->vi_int[1]);
853                         codenl();
854                         break;
855                 }
856         }
857         codecoco(cocono);
858         vil = vilength(yields);
859         if (vil!=0 || tokpatlen!=0 || allocates!=0) {
860                 code53(DO_TOKREPLACE,vilength(yields));
861                 for(vp=yields;vp!=0;vp=vp->vi_next) {
862                         codeint(vp->vi_int[0]);
863                 }
864                 codenl();
865         }
866         if (leaving!=0) {
867                 code53(DO_EMREPLACE,vilength(leaving));
868                 while (leaving!=0) {
869                         codeint(leaving->vi_int[0]);
870                         codeint(leaving->vi_int[1]);
871                         leaving = leaving->vi_next;
872                 }
873                 codenl();
874         }
875         if (totcost.ct_space!=0 || totcost.ct_time!=0) {
876                 code8(DO_COST);
877                 codeint(totcost.ct_space);
878                 codeint(totcost.ct_time);
879                 codenl();
880         }
881         if (empatlen==0 && !inproc)
882                 code8nl(DO_RETURN);
883         else
884                 code8nl(DO_NEXTEM);
885 }
886
887 used(resource,use,max) char *resource; {
888
889         if (verbose || 4*use > 3*max)
890                 fprintf(stderr,"%s %d(%d)\n",resource,use,max);
891 }
892
893 statistics() {
894         extern char *beg_sbrk,*sbrk();
895         extern int nnodes, maxempatlen,maxrule;
896
897         used("Registers",nregs,MAXREGS);
898         used("Properties",nprops,MAXPROPS);
899         used("Tokens",ntokens,MAXTOKENS);
900         used("Tokensize",maxtokensize,MAXATT);
901         used("Sets",nsets,MAXSETS);
902         used("Instructions",ninstr,MAXINSTR);
903         used("Strings",nstrings,MAXSTRINGS);
904         used("Exp-nodes",nnodes,MAXNODES);
905         used("EM-pat length",maxempatlen,EMPATMAX);
906         used("rules/EM-pattern",maxrule,MAXPATTERNS);
907         used("Allocates/rule",maxallreg,MAXALLREG);
908         used("Instances",ninstances,MAXINSTANCES);
909         used("Moves",nmoves,MAXMOVES);
910         used("Tests",ntests,MAXTESTS);
911         used("Stacks",nstacks,MAXSTACKS);
912         used("1->1 Coercions",ncoercs,MAXCOERCS);
913         used("Splitting coercions",nsplit,MAXSPLCOERC);
914         used("Register variables",maxregvars,MAXREGVAR);
915         used("Pat bytes",npatbytes+1,MAXPATBYTES);
916         if (tabledebug)
917                 used("Source lines",maxline,MAXSOURCELINES);
918         fprintf(stderr,"%ldK heap used\n",((long) (sbrk(0)-beg_sbrk+1023))/1024);
919 }