Pristine Ack-5.5
[Ack-5.5.git] / util / cgg / main.c
1 #include <stdio.h>
2 #include <assert.h>
3 #include <ctype.h>
4 #include <em_spec.h>
5 #include <em_flag.h>
6 #include <em_reg.h>
7
8 #include "booth.h"
9
10 extern char *strncpy(), *strcpy();
11 extern char *malloc();
12 #ifndef __STDC__
13 extern char *sprintf();
14 #else
15 /* sprintf should be declared in stdio.h, as returning an int */
16 #endif
17
18 char * myalloc(n) {
19         register char *p;
20
21         p= malloc((unsigned)n);
22         if (p==0) {
23                 yyerror("Out of core");
24                 exit(1);
25         }
26         return(p);
27 }
28
29 tstint(e) expr_t e; {
30
31         if(e.expr_typ != TYPINT)
32                 yyerror("Must be integer expression");
33 }
34
35 tstbool(e) expr_t e; {
36
37         if(e.expr_typ != TYPBOOL)
38                 yyerror("Must be boolean expression");
39 }
40
41 structsize(s) register list2 s; {
42         register list1 l;
43         register sum;
44
45         sum = 0;
46         while ( s != 0 ) {
47                 l = s->l2list->l1next;
48                 while ( l != 0 ) {
49                         sum++;
50                         l = l->l1next;
51                 }
52                 s = s->l2next;
53         }
54         return(sum);
55 }
56
57 list2 lookstruct(ll) list2 ll; {
58         list3 l3;
59         list2 l21,l22;
60         list1 l11,l12;
61
62         for (l3=structpool;l3 != 0;l3=l3->l3next) {
63                 for (l21=l3->l3list,l22=ll;l21!=0 && l22!=0;
64                      l21=l21->l2next,l22=l22->l2next) {
65                         for(l11=l21->l2list,l12=l22->l2list;
66                             l11!=0 && l12!=0 && strcmp(l11->l1name,l12->l1name)==0;
67                             l11=l11->l1next,l12=l12->l1next)
68                                 ;
69                         if (l11!=0 || l12!=0)
70                                 goto contin;
71                 }
72                 if(l21==0 && l22==0)
73                         return(l3->l3list);
74                 contin:;
75         }
76         l3 = (list3) myalloc(sizeof(struct list3str));
77         l3->l3next=structpool;
78         l3->l3list=ll;
79         structpool=l3;
80         return(ll);
81 }
82
83 instno(inst) inst_t inst; {
84         register i,j;
85
86         for(i=1;i<narinstance;i++) {
87                 if (arinstance[i].in_which != inst.in_which)
88                         continue;
89                 for(j=0;j<TOKENSIZE;j++)
90                         if(arinstance[i].in_info[j] != inst.in_info[j])
91                                 goto cont;
92                 return(i);
93         cont:;
94         }
95         chktabsiz(narinstance,MAXINSTANCE,"Instance table");
96         arinstance[narinstance] = inst;
97         return(narinstance++);
98 }
99
100 string scopy(s) string s; {
101         register string t;
102
103         t = (char *) myalloc(strlen(s)+1);
104         strcpy(t,s);
105         return(t);
106 }
107
108 strlookup(s) string s; {
109         register i;
110
111         for(i=0;i<ncodestrings;i++)
112                 if(strcmp(s,codestrings[i])==0)
113                         return(i);
114         chktabsiz(ncodestrings,MAXSTRINGS,"string table");
115         codestrings[ncodestrings] = scopy(s);
116         return(ncodestrings++);
117 }
118
119 stringno(s) register string s; {
120         char buf[256];
121         register char *p=buf;
122
123         while(*s != 0) switch(*s) {
124         default:
125                 *p++ = *s++;
126                 continue;
127         case '$':
128                 s++;
129                 switch(*s) {
130                 default:
131                         yyerror("Bad character after $ in codestring");
132                 case '$':
133                         *p++ = *s++;
134                         continue;
135                 case '1':
136                 case '2':
137                 case '3':
138                 case '4':
139                 case '5':
140                 case '6':
141                 case '7':
142                 case '8':
143                 case '9':
144                         *p++ = argtyp(patmnem[*s-'0']) == TYPINT ?
145                                 PR_EMINT : PR_EMSTR;
146                         *p++ = *s++ -'0';
147                         continue;
148                 }
149         case '%':
150                 s++;
151                 if (*s != '[') {
152                         if(*s == '%') {
153                                 *p++ = *s++;
154                                 continue;
155                         } else
156                                 yyerror("Bad character following %% in codestring");
157                 } else
158                         s++;
159                 if(isdigit(*s)) {
160                         int num;
161                         num = *s++ - '0';
162                         if (num<1 || num>tokpatlen)
163                                 yyerror("Number within %[] out of range");
164                         if (*s == ']') {
165                                 s++;
166                                 *p++ = PR_TOK;
167                                 *p++ = num;
168                         } else if (*s++ != '.')
169                                 yyerror("Bad character following %%[digit in codestring");
170                         else {
171                                 char field[256];
172                                 register char *f=field;
173                                 int type,offset;
174
175                                 while( *s != ']' && *s != 0)
176                                         *f++ = *s++;
177                                 *f++ = 0;
178                                 if (*s != ']')
179                                         yyerror("Unterminated %[] construction in codestring");
180                                 else
181                                         s++;
182                                 if (isdigit(field[0])) {
183                                         chkregexp(pattokexp[num]);
184                                         *p++ = PR_SUBREG;
185                                         *p++ = num;
186                                         *p++ = atoi(field);
187                                 } else {
188                                         offset = findstructel(pattokexp[num],field,&type);
189                                         *p++ = PR_TOKFLD;
190                                         *p++ = num;
191                                         *p++ = offset;
192                                 }
193                         }
194                 } else if (*s >= 'a' && *s < 'a'+nallreg) {
195                         int reg,subreg;
196                         reg = *s++ -'a'+1;
197                         if(*s == ']')
198                                 subreg = 255;
199                         else {
200                                 if (*s != '.')
201                                         yyerror("Bad character following %%[x in codestring");
202                                 s++;
203                                 if(!isdigit(*s))
204                                         yyerror("Bad character following %%[x. in codestring");
205                                 subreg = *s - '0';
206                                 s++;
207                                 if(*s != ']')
208                                         yyerror("Bad character following %%[x.y in codestring");
209                         }
210                         s++;
211                         *p++ = PR_ALLREG;
212                         *p++ = reg;
213                         *p++ = subreg;
214                 } else
215                         yyerror("Bad character following %%[ in codestring");
216         }
217         *p++ = 0;
218         return(strlookup(buf));
219 }
220
221 tabovf(tablename) string tablename; {
222         char buf[256];
223
224         sprintf(buf,"%s overflow",tablename);
225         yyerror(buf);
226         exit(-1);
227 }
228
229 main(argc,argv) char *argv[]; {
230
231         while (--argc) {
232                 ++argv;
233                 if (argv[0][0]=='-') {
234                         switch (argv[0][1]) {
235                         case 'h':
236                                 hname= &argv[0][2];
237                                 break;
238                         case 'c':
239                                 cname= &argv[0][2];
240                                 break;
241                         default:
242                                 fprintf(stderr,"Bad flag %s\n",argv[0]);
243                                 break;
244                         }
245                 } else {
246                         iname= argv[0];
247                 }
248         }
249         inithash();
250         initio();
251         inittables();
252         yyparse();
253         if (nerrors==0) {
254                 compueq();
255                 hashpatterns();
256                 finishio();
257                 verbose();
258         }
259         debug();
260         exit(nerrors);
261 }
262
263 lookup(comm,operator,lnode,rnode) {
264         register node_p p;
265
266         for (p=nodes+1;p<lastnode;p++) {
267                 if (p->ex_operator != operator)
268                         continue;
269                 if (!(p->ex_lnode == lnode && p->ex_rnode == rnode ||
270                     comm && p->ex_lnode == rnode && p->ex_rnode == lnode))
271                         continue;
272                 return(p-nodes);
273         }
274         if (lastnode >= &nodes[MAXNODES])
275                 yyerror("node table overflow");
276         lastnode++;
277         p->ex_operator = operator;
278         p->ex_lnode = lnode;
279         p->ex_rnode = rnode;
280         return(p-nodes);
281 }
282
283 compueq() {
284         register i,j;
285
286         for (i=1;i<nmachregs;i++) {
287                 for (j=1;j<i;j++)
288                         if (eqregclass(i,j)) {
289                                 stregclass[i] = stregclass[j];
290                                 break;
291                         }
292                 if (j==i)
293                         stregclass[i] = nregclasses++;
294         }
295 }
296
297 eqregclass(r1,r2) {
298         register reginfo rp1,rp2;
299         register i;
300         short regbits[(MAXREGS+15)>>4];
301         int member;
302
303         rp1 = machregs[r1]; rp2 = machregs[r2];
304         for (i=0;i<((nprops+15)>>4);i++)
305                 if (rp1->rprop[i] != rp2->rprop[i])
306                         return(0);
307         for (i=0;i<((MAXREGS+15)>>4);i++)
308                 regbits[i] = 0;
309         for (i=0;i<maxmembers;i++) {
310                 if (member = rp1->rmembers[i])
311                         regbits[member>>4] |= (1<<(member&017));
312         }
313         for (i=0;i<maxmembers;i++) {
314                 member = rp2->rmembers[i];
315                 if (regbits[member>>4]&(1<<(member&017)))
316                         return(0);
317         }
318         return(1);
319 }
320
321 unsigned hash(name) register string name; {
322         register unsigned sum;
323         register i;
324
325         for (sum=i=0;*name;i+=3)
326                 sum ^= (*name++)<<(i&07);
327         return(sum);
328 }
329
330 ident_p ilookup(name,enterf) string name; int enterf; {
331         register ident_p p,*pp;
332
333         pp = &identtab[hash(name)%ITABSIZE];
334         while (*pp != 0) {
335                 if (strcmp((*pp)->i_name,name)==0)
336                         if (enterf != ENTER)
337                                 return(*pp);
338                         else
339                                 yyerror("Multiply defined symbol");
340                 pp = &(*pp)->i_next;
341         }
342         if (enterf == LOOKUP)
343                 yyerror("Undefined symbol");
344         if (enterf == JUSTLOOKING)
345                 return(0);
346         p = *pp = (ident_p) myalloc(sizeof(ident_t));
347         p->i_name = name;
348         p->i_next = 0;
349         p->i_type = 0;
350         return(p);
351 }
352
353 initio() {
354
355         if (iname!=0 && freopen(iname,"r",stdin)==NULL) {
356                 fprintf(stderr,"Can't open %s\n",iname);
357                 exit(-1);
358         }
359         if ((cfile=fopen(cname,"w"))==NULL) {
360                 fprintf(stderr,"Can't create %s\n",cname);
361                 exit(-1);
362         }
363         if ((hfile=fopen(hname,"w"))==NULL) {
364                 fprintf(stderr,"Can't create %s\n",hname);
365                 exit(-1);
366         }
367         fprintf(cfile,"#include \"param.h\"\n");
368         fprintf(cfile,"#include \"tables.h\"\n");
369         fprintf(cfile,"#include \"types.h\"\n");
370         fprintf(cfile,"#include <cg_pattern.h>\n");
371         fprintf(cfile,"#include \"data.h\"\n");
372         fprintf(cfile,"\nbyte coderules[] = {\n");
373         patbyte(0);
374 }
375
376 exprlookup(sett) set_t sett; {
377         register i,j,ok;
378
379         for(i=0;i<nmachsets;i++) {
380                 ok= (sett.set_size == machsets[i].set_size);
381                 for(j=0;j<SETSIZE;j++) {
382                         if (sett.set_val[j] == machsets[i].set_val[j])
383                                 continue;
384                         ok=0;
385                         break;
386                 }
387                 if (ok)
388                         return(i);
389         }
390         chktabsiz(nmachsets,MAXSETS,"Expression table");
391         machsets[nmachsets] = sett;
392         return(nmachsets++);
393 }
394
395 inittables() {
396         register reginfo r;
397         register i;
398         inst_t inst;
399         set_t sett;
400
401         nodes[0].ex_operator=EX_CON;
402         nodes[0].ex_lnode=0;
403         nodes[0].ex_rnode=0;
404         cocopropno=nprops++;
405         r=(reginfo)myalloc(sizeof(struct reginfo));
406         r->rname = "cc reg";
407         r->rrepr = "CC";
408         r->rsize = -1;
409         r->rregvar= -1;
410         for(i=0;i<MAXMEMBERS;i++)
411                 r->rmembers[i] = 0;
412         for(i=0;i<PROPSETSIZE;i++)
413                 r->rprop[i] = 0;
414         r->rprop[cocopropno>>4] |= (1<<(cocopropno&017));
415         chktabsiz(nmachregs,MAXREGS,"Register table");
416         machregs[nmachregs++]  = r;
417         inst.in_which = IN_RIDENT;
418         inst.in_info[0] = nmachregs-1;
419         for(i=1;i<TOKENSIZE;i++)
420                 inst.in_info[i]=0;
421         ccinstanceno=instno(inst);
422         ccregexpr=lookup(0,EX_REG,nmachregs-1,0);
423         sett.set_size=0;
424         for (i=0;i<SETSIZE;i++)
425                 sett.set_val[i]=0;
426         sett.set_val[nmachregs>>4] |= (01<<(nmachregs&017));
427         cocosetno=exprlookup(sett);
428 }
429
430 outregs() {
431         register i,j,k;
432         static short rset[(MAXREGS+15)>>4];
433         int t,ready;
434
435         fprintf(cfile,"char stregclass[] = {\n");
436         for (i=0;i<nmachregs;i++)
437                 fprintf(cfile,"\t%d,\n",stregclass[i]);
438         fprintf(cfile,"};\n\nstruct reginfo machregs[] = {\n{0},\n");
439         for (i=1;i<nmachregs;i++) {
440                 fprintf(cfile,"{%d,%d",strlookup(machregs[i]->rrepr),
441                         machregs[i]->rsize);
442                 if (maxmembers!=0) {
443                         fprintf(cfile,",{");
444                         for(j=0;j<maxmembers;j++)
445                                 fprintf(cfile,"%d,",machregs[i]->rmembers[j]);
446                         /* now compute and print set of registers
447                          * that clashes with this register.
448                          * A register clashes with al its children (and theirs)
449                          * and with all their parents.
450                          */
451                         for (j=0;j<((MAXREGS+15)>>4);j++)
452                                 rset[j]=0;
453                         rset[i>>4] |= (1<<(i&017));
454                         do {
455                             ready=1;
456                             for (j=1;j<nmachregs;j++)
457                                 if (rset[j>>4]&(1<<(j&017)))
458                                     for (k=0;k<maxmembers;k++)
459                                         if ((t=machregs[j]->rmembers[k])!=0) {
460                                             if ((rset[t>>4]&(1<<(t&017)))==0)
461                                                 ready=0;
462                                             rset[t>>4] |= (1<<(t&017));
463                                         }
464                         } while (!ready);
465                         do {
466                             ready=1;
467                             for (j=1;j<nmachregs;j++)
468                                 for (k=0;k<maxmembers;k++)
469                                     if ((t=machregs[j]->rmembers[k])!=0)
470                                         if (rset[t>>4]&(1<<(t&017))) {
471                                                 if (rset[j>>4]&(1<<(j&017))==0)
472                                                     ready=0;
473                                                 rset[j>>4] |= (1<<(j&017));
474                                         }
475                         } while (!ready);
476                         fprintf(cfile,"},{");
477                         for (j=0;j<((nmachregs+15)>>4);j++)
478                                 fprintf(cfile,"%d,",rset[j]);
479                         fprintf(cfile,"}");
480                 }
481                 if (machregs[i]->rregvar>=0)
482                         fprintf(cfile,",1");
483                 fprintf(cfile,"},\n");
484         }
485         fprintf(cfile,"};\n\n");
486 }
487
488 finishio() {
489         register i;
490         register node_p np;
491         int j;
492         int setsize;
493         register move_p mp;
494
495         fprintf(cfile,"};\n\n");
496         if (wsize>0)
497                 fprintf(hfile,"#define TEM_WSIZE %d\n",wsize);
498         else
499                 yyerror("Wordsize undefined");
500         if (psize>0)
501                 fprintf(hfile,"#define TEM_PSIZE %d\n",psize);
502         else
503                 yyerror("Pointersize undefined");
504         if (bsize>=0)
505                 fprintf(hfile,"#define TEM_BSIZE %d\n",bsize);
506         else
507                 yyerror("EM_BSIZE undefined");
508         if (fmt!=0)
509                 fprintf(hfile,"#define WRD_FMT \"%s\"\n",fmt);
510         fprintf(hfile,"#define MAXALLREG %d\n",maxallreg);
511         setsize = (nmachregs+1 + nmachtokens + 15)>>4;
512         fprintf(hfile,"#define SETSIZE %d\n",setsize);
513         fprintf(hfile,"#define NPROPS %d\n",nprops);
514         fprintf(hfile,"#define NREGS %d\n",nmachregs);
515         fprintf(hfile,"#define REGSETSIZE %d\n",(nmachregs+15)>>4);
516         fprintf(hfile,"#define TOKENSIZE %d\n",maxtokensize);
517         fprintf(hfile,"#define MAXMEMBERS %d\n",maxmembers);
518         fprintf(hfile,"#define LONGESTPATTERN %d\n",maxempatlen);
519         fprintf(hfile,"#define MAXRULE %d\n",maxrule);
520         fprintf(hfile,"#define NMOVES %d\n",nmoves);
521         fprintf(hfile,"#define NC1 %d\n",nc1);
522         if (nc2) {
523                 assert(maxsplit!=0);
524                 fprintf(hfile,"#define NC2 %d\n",nc2);
525                 fprintf(hfile,"#define MAXSPLIT %d\n",maxsplit);
526         }
527         fprintf(hfile,"#define NC3 %d\n",nc3);
528         outregs();
529         fprintf(cfile,"tkdef_t tokens[] = {\n");
530         for(i=0;i<nmachtokens;i++) {
531                 fprintf(cfile,"{%d,{%d,%d},{",machtokens[i].t_size,
532                                 machtokens[i].t_cost.c_size,
533                                 machtokens[i].t_cost.c_time);
534                 for(j=0;j<maxtokensize;j++)
535                         fprintf(cfile,"%d,",machtokens[i].t_fields[j].t_type);
536                 fprintf(cfile,"},%d},\n",machtokens[i].t_format);
537         }
538         fprintf(cfile,"};\n\nnode_t enodes[] = {\n");
539         for(np=nodes;np<lastnode;np++)
540                 fprintf(cfile,"{%d,%d,%d},\n",np->ex_operator,np->ex_lnode,
541                                 np->ex_rnode);
542         fprintf(cfile,"};\n\nstring codestrings[] = {\n");
543         for(i=0;i<ncodestrings;i++) {
544                 register char *p;
545                 p=codestrings[i];
546                 fprintf(cfile,"\t\"");
547                 while (*p) {
548                         register int c = (*p) & BMASK;
549                         if (! isascii(c) || iscntrl(c)) {
550                                 /* The next line used to have (c>>6)&03,
551                                    but this triggered a bug in GCC 2.4.5
552                                    on SPARC.
553                                 */
554                                 fprintf(cfile,"\\%c%c%c",((*p>>6) &03)+'0',
555                                         ((c>>3)&07)+'0',(c&07)+'0');
556                         }
557                         else    putc(c, cfile);
558                         p++;
559                 }
560                 fprintf(cfile,"\",\n");
561         }
562         fprintf(cfile,"};\n\nset_t machsets[] = {\n");
563         for(i=0;i<nmachsets;i++) {
564                 fprintf(cfile,"{%d,{",machsets[i].set_size);
565                 for(j=0;j<setsize;j++)
566                         fprintf(cfile,"0%o,",machsets[i].set_val[j] & 0xFFFF);
567                 fprintf(cfile,"}},\n");
568         }
569         fprintf(cfile,"};\n\ninst_t tokeninstances[] = {\n");
570         for(i=0;i<narinstance;i++) {
571                 fprintf(cfile,"{ %d, {",arinstance[i].in_which);
572                 for(j=0;j<=maxtokensize;j++)
573                         fprintf(cfile,"%d,",arinstance[i].in_info[j]);
574                 fprintf(cfile,"}},\n");
575         }
576         fprintf(cfile,"};\n\nmove_t moves[] = {\n");
577         for (i=0;i<nmoves;i++) {
578                 mp = &machmoves[i];
579                 fprintf(cfile,"{%d,%d,%d,%d,%d,{%d,%d}},\n",
580                         mp->m_set1, mp->m_expr1,
581                         mp->m_set2, mp->m_expr2,
582                         mp->m_cindex,
583                         mp->m_cost.c_size,mp->m_cost.c_time);
584         }
585         fprintf(cfile,"};\n\nbyte pattern[] = {\n");
586         for (i=0;i<npatbytes;i++) {
587                 fprintf(cfile,"%3d,",pattern[i]&BMASK);
588                 if ((i%10)==9)
589                         fprintf(cfile,"\n");
590         }
591         fprintf(cfile,"\n};\n\nint pathash[256] = {\n");
592         for(i=0;i<256;i++) {
593                 fprintf(cfile,"%6d,",pathash[i]);
594                 if((i&07)==07)
595                         fprintf(cfile,"\n");
596         }
597         fprintf(cfile,"};\n\nc1_t c1coercs[] = {\n");
598         for (i=0;i<nc1;i++)
599                 fprintf(cfile,"{%d,%d,%d,%d,{%d,%d}},\n",
600                         c1coercs[i].c1_texpno,
601                         c1coercs[i].c1_expr,
602                         c1coercs[i].c1_prop,
603                         c1coercs[i].c1_codep,
604                         c1coercs[i].c1_cost.c_size,
605                         c1coercs[i].c1_cost.c_time);
606         if (nc2)
607                 fprintf(cfile,"};\n\nc2_t c2coercs[] = {\n");
608         for (i=0;i<nc2;i++) {
609                 fprintf(cfile,"{%d,%d,{",
610                         c2coercs[i].c2_texpno,
611                         c2coercs[i].c2_nsplit);
612                 for (j=0;j<maxsplit;j++)
613                         fprintf(cfile,"%d,",c2coercs[i].c2_repl[j]);
614                 fprintf(cfile,"},%d},\n",c2coercs[i].c2_codep);
615         }
616         fprintf(cfile,"};\n\nc3_t c3coercs[] = {\n");
617         for (i=0;i<nc3;i++)
618                 fprintf(cfile,"{%d,%d,%d,%d},\n",
619                         c3coercs[i].c3_texpno,
620                         c3coercs[i].c3_prop,
621                         c3coercs[i].c3_repl,
622                         c3coercs[i].c3_codep);
623         fprintf(cfile,"};\n\n");
624         for (i=0;i<nprops;i++) {
625                 fprintf(cfile,"struct reginfo *rlist%d[] = {\n",i);
626                 for (j=2;j<=nmachregs;j++) {
627                         if (machregs[j-1]->rregvar<0 && 
628                             (machprops[i].propset.set_val[j>>4]&(1<<(j&017))))
629                                 fprintf(cfile,"\t&machregs[%d],\n",j-1);
630                 }
631                 fprintf(cfile,"\t0\n};\n");
632         }
633         fprintf(cfile,"struct reginfo **reglist[] = {\n");
634         for (i=0;i<nprops;i++) {
635                 fprintf(cfile,"\trlist%d,\n",i);
636         }
637         fprintf(cfile,"};\n");
638         fprintf(cfile,"unsigned cc1 = %u;\n",cc1);
639         fprintf(cfile,"unsigned cc2 = %u;\n",cc2);
640         fprintf(cfile,"unsigned cc3 = %u;\n",cc3);
641         fprintf(cfile,"unsigned cc4 = %u;\n",cc4);
642         if (rvused)
643                 outregvar();
644 }
645
646 outregvar() {
647         register i,j;
648
649         fprintf(hfile,"#define REGVARS\n");
650         fprintf(cfile,"#include \"regvar.h\"\n");
651         fprintf(cfile,"int nregvar[4] = { ");
652         for (i=0;i<4;i++) fprintf(cfile,"%d, ",nregvar[i]);
653         fprintf(cfile,"};\n");
654         for (i=0;i<4;i++)
655                 if (nregvar[i]>0)
656                         fprintf(cfile,"struct regassigned ratar%d[%d];\n",
657                                         i,nregvar[i]);
658         for (i=0;i<4;i++) if (nregvar[i]>0) {
659                 fprintf(cfile,"int rvtar%d[] = {",i);
660                 for (j=0;j<nregvar[i];j++)
661                         fprintf(cfile,"%d,",rvnumbers[i][j]);
662                 fprintf(cfile,"};\n");
663         }
664         fprintf(cfile,"\nint *rvnumbers[] = {\n");
665         for (i=0;i<4;i++)
666                 if (nregvar[i]>0)
667                         fprintf(cfile,"\trvtar%d,\n",i);
668                 else
669                         fprintf(cfile,"\t0,\n");
670         fprintf(cfile,"};\n\nstruct regassigned *regassigned[] = {\n");
671         for (i=0;i<4;i++)
672                 if (nregvar[i]>0)
673                         fprintf(cfile,"\tratar%d,\n",i);
674                 else
675                         fprintf(cfile,"\t0,\n");
676         fprintf(cfile,"};\n");
677 }
678
679 verbose() {
680
681         fprintf(stderr,"Codebytes %d\n",codebytes);
682         fprintf(stderr,"Registers %d(%d)\n",nmachregs,MAXREGS);
683         fprintf(stderr,"Properties %d(%d)\n",nprops,MAXPROPS);
684         fprintf(stderr,"Tokens %d(%d)\n",nmachtokens,MAXTOKENS);
685         fprintf(stderr,"Sets %d(%d)\n",nmachsets,MAXSETS);
686         fprintf(stderr,"Tokeninstances %d(%d)\n",narinstance,MAXINSTANCE);
687         fprintf(stderr,"Strings %d(%d)\n",ncodestrings,MAXSTRINGS);
688         fprintf(stderr,"Enodes %d(%d)\n",lastnode-nodes,MAXNODES);
689         fprintf(stderr,"Patbytes %d(%d)\n",npatbytes,MAXPATTERN);
690 }
691
692 inbetween() {
693         register ident_p ip;
694         register i,j;
695         register move_p mp;
696
697         lookident=1;    /* for lexical analysis */
698
699         chktabsiz(nmachsets+1,MAXSETS,"Expressiontable");
700         for (i=0;i<SETSIZE;i++)
701                 machsets[nmachsets].set_val[i] = 0xFFFF;
702         machsets[nmachsets].set_val[0] &= ~1;
703         machsets[nmachsets].set_size = 0;
704         ip=ilookup("SCRATCH",ENTER);
705         ip->i_type=IEXP;
706         ip->i_i.i_expno = nmachsets++;
707
708         for (i=0;i<SETSIZE;i++)
709                 machsets[nmachsets].set_val[i] = 0xFFFF;
710         machsets[nmachsets].set_size = 0;
711         ip=ilookup("ALL",ENTER);
712         ip->i_type=IEXP;
713         allexpno = ip->i_i.i_expno = nmachsets++;
714         mp = &machmoves[nmoves++];
715         mp->m_set1 = cocosetno;
716         mp->m_expr1 = 0;
717         mp->m_set2 = nmachsets-1;
718         mp->m_expr2 = 0;
719         mp->m_cindex = 0;
720         mp->m_cost.c_size = 0;
721         mp->m_cost.c_time = 0;
722
723         /*
724          * Create sets of registers per property
725          */
726
727         for (i=0;i<nprops;i++) {
728                 short *sp = machprops[i].propset.set_val;
729
730                 sp[0] |= 1;
731                 for (j=2;j<=nmachregs;j++)
732                         if (machregs[j-1]->rprop[i>>4]&(1<<(i&017)))
733                                 sp[j>>4] |= (1<<(j&017));
734         }
735 }
736
737 formconversion(p,tp) register char *p; register token_p tp; {
738         char buf[256];
739         register char *q=buf;
740         char field[256];
741         register char *f;
742         int i;
743
744         if (p==0)
745                 return(0);
746         while (*p) switch(*p) {
747         default: *q++ = *p++; continue;
748         case '%':
749                 p++;
750                 if(*p == '%') {
751                         *q++ = *p++;
752                         continue;
753                 }
754                 if (*p == '[')
755                         p++;
756                 else
757                         yyerror("Bad character after % in format");
758                 f=field;
759                 while (*p != 0 && *p != ']')
760                         *f++ = *p++;
761                 *f++ = 0;
762                 if (*p == ']')
763                         p++;
764                 else
765                         yyerror("Unterminated %[] construct in format");
766                 for (i=0;i<TOKENSIZE-1;i++)
767                         if (strcmp(field,tp->t_fields[i].t_sname)==0)
768                                 break;
769                 if (i==TOKENSIZE-1)
770                         yyerror("Unknown field in %[] construct in format");
771                 *q++ = i+1;
772         }
773         *q++ = 0;
774         return(strlookup(buf));
775 }
776
777 setfields(tp,format) register token_p tp; string format; {
778         register i;
779         list2 ll;
780         register list1 l;
781         int type;
782
783         for(i=0;i<TOKENSIZE-1;i++)
784                 tp->t_fields[i].t_type = 0;
785         i=0;
786         for(ll=tp->t_struct;ll!=0;ll=ll->l2next) {
787                 l=ll->l2list;
788                 if(strcmp(l->l1name,"REGISTER")==0)
789                         type = TYPREG;
790                 else if (strcmp(l->l1name,"INT")==0)
791                         type = TYPINT;
792                 else    type = TYPSTR;
793                 for(l=l->l1next;l!=0;l=l->l1next) {
794                         tp->t_fields[i].t_type = type;
795                         tp->t_fields[i].t_sname = l->l1name;
796                         i++;
797                 }
798         }
799         if (format != 0)
800                 tp->t_format = formconversion(format,tp);
801         else
802                 tp->t_format = -1;
803 }
804
805 chkregexp(number) {
806         register i;
807
808         for(i=nmachregs+1;i<nmachregs+1+nmachtokens;i++)
809                 if(machsets[number].set_val[i>>4]&(01<<(i&017)))
810                         yyerror("No tokens allowed in this set");
811 }
812
813 findstructel(number,name,t) string name; int *t; {
814         register i;
815         register token_p tp;
816         register list2 structdecl;
817         int offset;
818
819         for(i=1;i<=nmachregs;i++)
820                 if (machsets[number].set_val[i>>4]&(01<<(i&017)))
821                         yyerror("No registers allowed in this set");
822         structdecl = 0;
823         for (i=nmachregs+1;i<nmachregs+1+nmachtokens;i++) {
824                 if (machsets[number].set_val[i>>4]&(01<<(i&017))) {
825                         if (structdecl == 0) {
826                                 structdecl = machtokens[i-(nmachregs+1)].t_struct;
827                                 tp = &machtokens[i-(nmachregs+1)];
828                         } else if(structdecl != machtokens[i-(nmachregs+1)].t_struct)
829                                         yyerror("Multiple structs in this set");
830                 }
831         }
832         if (structdecl == 0) {
833                 yyerror("No structs in this set");
834                 return(0);
835         }
836         for(offset=0;offset<TOKENSIZE-1;offset++)
837                 if(tp->t_fields[offset].t_type != 0 &&
838                    strcmp(tp->t_fields[offset].t_sname,name)==0) {
839                         *t = tp->t_fields[offset].t_type;
840                         return(offset+1);
841                 }
842         yyerror("No such field in this struct");
843         return(0);
844 }
845
846 extern char em_flag[];
847
848 argtyp(mn) {
849
850         switch(em_flag[mn-sp_fmnem]&EM_PAR) {
851         case PAR_W:
852         case PAR_S:
853         case PAR_Z:
854         case PAR_O:
855         case PAR_N:
856         case PAR_L:
857         case PAR_F:
858         case PAR_R:
859         case PAR_C:
860                 return(TYPINT);
861         default:
862                 return(TYPSTR);
863         }
864 }
865
866 commontype(e1,e2) expr_t e1,e2; {
867
868         if(e1.expr_typ != e2.expr_typ)
869                 yyerror("Type incompatibility");
870         return(e1.expr_typ);
871 }
872
873 extern char em_mnem[][4];
874
875 #define HASHSIZE        (2*(sp_lmnem-sp_fmnem))
876
877 struct hashmnem {
878         char h_name[3];
879         byte h_value;
880 } hashmnem[HASHSIZE];
881
882 inithash() {
883         register i;
884
885         for(i=0;i<=sp_lmnem-sp_fmnem;i++)
886                 enter(em_mnem[i],i+sp_fmnem);
887 }
888
889 enter(name,value) char *name; {
890         register unsigned h;
891
892         h=hash(name)%HASHSIZE;
893         while (hashmnem[h].h_name[0] != 0)
894                 h = (h+1)%HASHSIZE;
895         strncpy(hashmnem[h].h_name,name,3);
896         hashmnem[h].h_value = value;
897 }
898
899 int mlookup(name) char *name; {
900         register unsigned h;
901
902         h = hash(name)%HASHSIZE;
903         while (strncmp(hashmnem[h].h_name,name,3) != 0 &&
904                hashmnem[h].h_name[0] != 0)
905                 h = (h+1)%HASHSIZE;
906         return(hashmnem[h].h_value&BMASK);      /* 0 if not found */
907 }
908
909 hashpatterns() {
910         short index;
911         register byte *bp,*tp;
912         register short i;
913         unsigned short hashvalue;
914         int patlen;
915
916         index = prevind;
917         while (index != 0) {
918                 bp = &pattern[index];
919                 tp = &bp[PO_MATCH];
920                 i = *tp++&BMASK;
921                 if (i==BMASK) {
922                         i = *tp++&BMASK;
923                         i |= (*tp++&BMASK)<<BSHIFT;
924                 }
925                 patlen = i;
926                 hashvalue = 0;
927                 switch(patlen) {
928                 default:        /* 3 or more */
929                         hashvalue = (hashvalue<<4)^(*tp++&BMASK);
930                 case 2:
931                         hashvalue = (hashvalue<<4)^(*tp++&BMASK);
932                 case 1:
933                         hashvalue = (hashvalue<<4)^(*tp++&BMASK);
934                 }
935                 assert(hashvalue!= ILLHASH);
936                 i=index;
937                 index = (bp[PO_NEXT]&BMASK)|(bp[PO_NEXT+1]<<BSHIFT);
938                 bp[PO_HASH] = hashvalue>>BSHIFT;
939                 hashvalue &= BMASK;
940                 bp[PO_NEXT] = pathash[hashvalue]&BMASK;
941                 bp[PO_NEXT+1] = pathash[hashvalue]>>BSHIFT;
942                 pathash[hashvalue] = i;
943         }
944 }
945
946 debug() {
947         register i,j;
948
949         for(i=0;i<ITABSIZE;i++) {
950                 register ident_p ip;
951                 for(ip=identtab[i];ip!=0;ip=ip->i_next)
952                         printf("%-14s %1d %3d\n",ip->i_name,
953                                 ip->i_type,ip->i_i.i_regno);
954         }
955
956         for(i=2;i<nmachregs;i++) {
957                 register reginfo rp;
958
959                 rp=machregs[i];
960                 printf("%s = (\"%s\", %d",rp->rname,rp->rrepr,rp->rsize);
961                 for(j=0;j<MAXMEMBERS;j++)
962                         if(rp->rmembers[j] != 0)
963                                 printf(", %s",machregs[rp->rmembers[j]]->rname);
964                 printf(")");
965                 for(j=0;j<nprops;j++)
966                         if(rp->rprop[j>>4]&(1<<(j&017)))
967                                 printf(", %s",machprops[j].propname->i_name);
968                 printf(".\n");
969         }
970 }
971
972 out(n) {
973
974         assert(n>=0);
975         if (n<128)
976                 outbyte(n);
977         else {
978                 outbyte(n/256+128);
979                 outbyte(n%256);
980         }
981 }
982
983 outbyte(n) {
984
985         fprintf(cfile,"%d, ",n&BMASK);
986         codebytes++;
987 }
988
989 pat(n) {
990
991         assert(n>=0);
992         if (n<128)
993                 patbyte(n);
994         else {
995                 patbyte(n/256+128);
996                 patbyte(n%256);
997         }
998 }
999
1000 patshort(n) {
1001
1002         patbyte(n&BMASK);
1003         patbyte(n>>BSHIFT);
1004 }
1005
1006 patbyte(n) {
1007
1008         chktabsiz(npatbytes,MAXPATTERN,"Pattern table");
1009         pattern[npatbytes++] = n;
1010 }
1011
1012 max(a,b) {
1013
1014         if (a>b)
1015                 return(a);
1016         return(b);
1017 }