|
|
1.1 root 1: /* @(#) sty.y: 1.1 12/22/83 */
2: %{
3: static char SCCSID[] = "@(#) sty.y: 1.1 83/08/02";
4: /*
5: This program turns machine descriptions into a table.c file
6: */
7: %}
8: /* The input language uses many C conventions and notations */
9: /* Types are represented as a shorthand:
10: c char
11: i int
12: s short
13: l long
14: p pointer
15: P alternate form of pointer
16: t structure
17: v void
18: ux unsigned x
19: f float
20: d double
21: /* There are a number of builtin cost names:
22: NONAME a constant with no name field (not an address)
23: CONVAL n the constant n
24: NCONVAL n the constant -n
25: POSRANGE n constants in the range [0,2**n -1]
26: SGRANGE n constants in the range [-2**n, 2**n - 1]
27: */
28: /* There are also several incedental needs, etc, specified
29: 1,2,3 Number of needed registers
30: $P need pairs
31: $< share left
32: $> share right
33: $L result left
34: $R result right
35: $1,2,3 result in reg 1, 2, 3
36: $C operation produces correct condition codes
37: $N no value produced: side effects only
38: $A need them all
39: $[ share left, RHS is preferred (if a temp register)
40: $] share right, RHS is preferred (if a temp register)
41: $l left side is referenced once more
42: $r right side is referenced once more
43: */
44:
45: /* NOTE:
46: When several templates match with equal cost, the first is chosen.
47: Thus, when side-effects only are desired, the first template matching
48: is taken, if it is of lowest cost.
49: Moral: $N templates should be cheaper or should preceed $L, $1, etc.
50: */
51:
52: %{
53: # include "ctype.h"
54: # include "mfile2.h"
55: # include "dope.h"
56:
57: typedef struct {
58: int sha; /* shape */
59: int ty; /* type */
60: } SHTY;
61: SHTY lshty, /* left and right shape type */
62: rshty;
63: static int dcost = 0; /* default cost */
64: static int op,
65: tyop,
66: needs,
67: rewrite,
68: cost;
69: static int lcount, rcount;
70: static int opno;
71: static int ophd[DSIZE];
72: static int optl[DSIZE];
73: static int opsh[DSIZE];
74:
75: struct optb { /* operation table */
76: int op; /* what operation is to be matched */
77: int tyop; /* the type associated with the op node */
78: int nxop; /* index of the next op */
79: int line; /* stin file line number */
80: SHTY l, /* shapes of the left side */
81: r; /* right side */
82: int oneeds, /* needs */
83: orew, /* rewrite info */
84: ocost; /* op cost */
85: char *string;/* the output */
86: int strdef,
87: struse;
88: int olcount,/* usage count for left side */
89: orcount;/* and right side */
90: };
91: typedef struct optb OPTB;
92:
93: # ifndef NOPTB
94: # define NOPTB 400
95: # endif
96:
97: OPTB optb[NOPTB];
98:
99: # ifndef NSTRING
100: # define NSTRING 10000
101: # endif
102:
103: # ifndef NSTYSHPS
104: # define NSTYSHPS 4000
105: # endif
106:
107: typedef struct {
108: int sop,
109: sleft,
110: sright,
111: ssh,
112: scset, /* ==1 after cost for shape has been set, else 0 */
113: scost,
114: scnt;
115: char shname[8];
116: } STYSHP;
117:
118: static int was_cost; /* set if a cost was actually specified */
119: static int nshp = 0;
120: static int nmshp = NSTYSHPS - 1;
121: /*static*/ STYSHP shp[NSTYSHPS];
122: static char strng[NSTRING];
123: static char *string;
124: static char *pstring = strng;
125: static char *asstring;
126:
127: %}
128:
129: %union {
130: int ival;
131: char *str;
132: SHTY shh;
133: };
134:
135: %token STR DEF LPRF RPRF LSHR RSHR GOODCC NOVAL PNEED LRES RRES LCOUNT RCOUNT
136: %token USERCOST CONVAL NCONVAL POSRANGE SGRANGE NONAME DCOST SHAPES OPCODES
137: %token <ival> OP NM DIG STYPE RREG
138: %left OP
139: %left STYPE
140:
141: %type <str> STR
142: %type <ival> opcost num slist nterm opop shape
143: %type <ival> costnexp nexp
144: %type <ival> cost cexpr cterm
145: %type <shh> sref
146:
147: /*
148: OP the ops <, <<, >, >>, <=, >=, +, -, *, /, %, &, ^, ~, !
149: NM names (letter, followed by 0 or more letters or digits
150: STR a string in ""
151: DIG a digit, 0-9
152: Other letters are returned: (, ), {, }, etc.
153: */
154:
155: %%
156:
157: file : SHAPES lshapes OPCODES lops
158: { finished(); }
159: ;
160:
161: lshapes : /* EMPTY */
162: | lshapes NM ':' slist ',' costnexp ';'
163: { shp[$2].sop = MANY;
164: shp[$2].sleft = $4;
165: shp[$2].sright = $6;
166: shp[$2].scost = 0;
167: shp[$2].scset = 1;
168: shp[$2].ssh = 0;
169: }
170: | lshapes NM ':' costnexp ';'
171: {
172: shp[$2].sop = MANY;
173: shp[$2].sleft = $4;
174: shp[$2].sright = -1;
175: shp[$2].scost = 0;
176: shp[$2].scset = 1;
177: shp[$2].ssh = 0;
178: }
179: | lshapes NM ':' opop shape opcost ';'
180: { shp[nshp].scost = $6;
181: shp[nshp].scset = was_cost;
182: shp[nshp].ssh = $5;
183: shp[nshp].sop = $4;
184: shp[nshp].sleft = -1;
185: shp[nshp].sright = -1;
186: ++nshp;
187: checkit( nshp-1 );
188: shp[$2].sop = MANY;
189: shp[$2].sleft = nshp-1;
190: shp[$2].sright = -1;
191: shp[$2].scost = 0;
192: shp[$2].scset = 1;
193: shp[$2].ssh = 0;
194: if( nshp >= nmshp ) {
195: yyerror( "out of node space" );
196: exit( 1 );
197: }
198: }
199: ;
200:
201: opop : /* EMPTY */
202: { $$ = ICON; }
203: | OP
204: ;
205:
206: lops : /* EMPTY */
207: { needs = op = rewrite = cost = 0;
208: lcount = rcount = 1;
209: }
210:
211: | lops lop
212: ;
213:
214: lop : OP sref ',' sref ltail
215: { lshty = $2;
216: rshty = $4;
217: op = $1;
218: tyop = TANY;
219: output();
220: tyop = needs = op = rewrite = cost = 0;
221: lcount = rcount = 1;
222: }
223: | OP STYPE sref ',' sref ltail
224: { lshty = $3;
225: rshty = $5;
226: op = $1;
227: tyop = $2;
228: output();
229: tyop = needs = op = rewrite = cost = 0;
230: lcount = rcount = 1;
231: }
232: | OP sref ltail
233: { lshty = $2;
234: rshty.sha = -1;
235: rshty.ty = TANY;
236: op = $1;
237: tyop = TANY;
238: output();
239: tyop = needs = op = rewrite = cost = 0;
240: lcount = rcount = 1;
241: }
242: | OP STYPE sref ltail
243: { lshty = $3;
244: rshty.sha = -1;
245: rshty.ty = $2;
246: op = $1;
247: tyop = TANY;
248: output();
249: tyop = needs = op = rewrite = cost = 0;
250: lcount = rcount = 1;
251: }
252: | sref ltail
253: { rshty = $1;
254: lshty.sha = -1;
255: lshty.ty = TANY;
256: loutput();
257: tyop = needs = op = rewrite = cost = 0;
258: lcount = rcount = 1;
259: }
260: | DCOST {dcost=0;} opcost ';'
261: { dcost = $3; }
262: ;
263:
264: ltail : needs STR opcost ';'
265: {
266: cost = $3;
267: asstring = $2;
268: }
269: ;
270:
271: needs : /* EMPTY */
272: { needs = 0; }
273: | '{' nlist '}'
274: ;
275:
276: nlist : /* EMPTY */
277: { needs = 0; }
278: | nlist DIG
279: { needs = (needs&~NCOUNT) | $2; }
280: | nlist RPRF
281: { needs |= RSHARE|RPREF; }
282: | nlist LPRF
283: { needs |= LSHARE|LPREF; }
284: | nlist RSHR
285: { needs |= RSHARE; }
286: | nlist LSHR
287: { needs |= LSHARE; }
288: | nlist PNEED
289: { needs |= NPAIR; }
290: | nlist GOODCC
291: { rewrite |= RESCC; }
292: | nlist NOVAL
293: {
294: if (rewrite)
295: yyerror("$N incompatible with other results");
296: rewrite = RNULL;
297: }
298: | nlist LRES
299: { rewrite |= RLEFT; }
300: | nlist RRES
301: { rewrite |= RRIGHT; }
302: | nlist RREG
303: { if( !(needs&NCOUNT) ) needs |= $2;
304: rewrite |= (($2==1)?RESC1:(($2==2)?RESC2:RESC3));
305: }
306: | nlist LCOUNT
307: { lcount += 1; }
308: | nlist RCOUNT
309: { rcount += 1; }
310: ;
311:
312: num : DIG
313: | num DIG
314: { $$ = 10*$1 + $2; }
315: ;
316:
317: opcost : cost
318: { was_cost = 1; }
319: | /* EMPTY */
320: { was_cost = 0; $$ = dcost; }
321: ;
322:
323: cost : ':' cexpr
324: { $$ = $2; }
325: ;
326:
327: cexpr : cterm
328: | OP cterm
329: { $$ = uopcost( $1, $2 ); }
330: | cterm OP cterm
331: { $$ = bopcost( $2, $1, $3 ); }
332: ;
333:
334: cterm : '(' cexpr ')'
335: { $$ = $2; }
336: | num
337: ;
338:
339: shape : /* EMPTY */
340: { $$ = 0; }
341: | NONAME
342: { $$ = NACON; /* constant with no name */ }
343: | USERCOST num
344: { $$ = $2|SUSER; /* user's cost ftn */ }
345: | CONVAL num
346: { $$ = $2|SVAL; /* positive constant value */ }
347: | NCONVAL num
348: { $$ = $2|SNVAL; /* negative constant value */ }
349: | POSRANGE num
350: { $$ = $2|SRANGE0; /* positive range */ }
351: | SGRANGE num
352: { $$ = $2|SSRANGE; /* signed range */ }
353: ;
354:
355: sref : nterm
356: { $$.ty = 0;
357: $$.sha = $1;
358: }
359: | nterm STYPE /* do this before doing in nterm */
360: { $$.sha = $1;
361: $$.ty = $2; }
362: ;
363:
364: slist : costnexp
365: | slist ',' costnexp
366: { $$ = bop( MANY, $1, $3, 0 ); }
367: ;
368:
369: costnexp: nexp opcost
370: { $$ = sharecost($1, $2); }
371: ;
372:
373: nexp : nterm
374: | OP nterm
375: { $$ = uop( $1, $2 ); }
376: | nterm OP nterm
377: { $$ = bop( $2, $1, $3, 0 ); }
378: ;
379:
380: nterm : '(' nexp ')'
381: { $$ = $2; }
382: | NM
383: | nterm STYPE
384: { $$ = top( $1, $2 ); }
385: ;
386:
387: %%
388: static int lineno = 1; /* line number of stin file */
389: static char filename[100] = "<stdin>";
390:
391: main(argc, argv)
392: int argc;
393: char **argv;
394: {
395: register int i;
396: for( i=0; i<DSIZE; ++i ) {
397: opsh[i] = 0;
398: optl[i] = ophd[i] = -1;
399: }
400: mkdope();
401: yyparse();
402: exit( 0 );
403: }
404:
405:
406: checkit( n )
407: {
408: /* check a shape */
409: STYSHP *p;
410: if( n<0 ) return;
411: if( n>=nshp && n<=nmshp || n>=NSTYSHPS ) {
412: yyerror( "out of range shape: %d", n );
413: }
414: p = &shp[n];
415: if( p->sop < 0 || p->sop > MANY ) {
416: yyerror( "out of range op: %d", p->sop );
417: }
418:
419: switch( optype(p->sop) ) {
420:
421: case BITYPE:
422: if( p->sright < 0 && p->sop != MANY ) {
423: yyerror( "right side empty" );
424: }
425: checkit( p->sright );
426: case UTYPE:
427: if( p->sleft < 0 ) {
428: yyerror( "left side empty" );
429: }
430: checkit( p->sleft );
431: }
432: }
433:
434: /* VARARGS */
435: yyerror( s, a )
436: char *s;
437: {
438: fprintf( stderr, s, a );
439: fprintf( stderr, ", file \"%s\", line %d\n", filename, lineno );
440: abort();
441: exit( 1 );
442: }
443:
444:
445: static int otb[20]; /* ops that are part of the shape */
446: static int notb; /* number of otb entries */
447:
448: loutput()
449: {
450: /*
451: * rhs has a leaf: output templates for all interesting
452: * operators in this leaf.
453: * An interesting operator is one that is NOT MANY.
454: * This allows us to access the table for each operator
455: * that this leaf may implement.
456: */
457: register int i;
458: register int s;
459: register int ocost = cost;
460:
461: notb = 0;
462: lout1( s = rshty.sha );
463: if( !notb ) yyerror( "lout1() error" );
464: for( i = notb-1; i >= 0; --i )
465: {
466: op = otb[i];
467: tyop = TANY;
468: if( optype(op) == LTYPE ) {
469: lcount = 0;
470: cost = ocost + (rcount * refine(s));
471: }
472: else if( optype(op) == BITYPE ) {
473: yyerror( "binary op in shape not done right" );
474: }
475: else { /* op is unary */
476: lcount = rcount;
477: rcount = 0;
478: cost = ocost + (lcount * urefine(s));
479: }
480: output();
481: }
482: }
483:
484: urefine( s ) { /* construct an entry for a unary op matching shape s */
485: /* for now, punt on the costs */
486: rcount = lcount;
487: lcount = 0;
488: return( refine( s ) );
489: }
490:
491: smat(s)
492: register s;
493: {
494: /*
495: * return 1 if we can find the op anyplace in the
496: * shape tree `s'
497: */
498: if( s < 0 )
499: return( 0 );
500: if( shp[s].sop == MANY )
501: {
502: if( shp[s].sleft>=0 && smat( shp[s].sleft ) ) return( 1 );
503: if( shp[s].sright>=0 && smat( shp[s].sright ) ) return( 1 );
504: return( 0 );
505: }
506: return( shp[s].sop == op );
507: }
508:
509: refine(s)
510: register s;
511: {
512: /*
513: * find the largest subshape of `s' that contains
514: * the operator `op' (op is global).
515: * We descend MANY nodes until we run out,
516: * or until the operator `op' is found in both descendents.
517: * Since we are throwing away costs buried in the MANY nodes
518: * on the way down, we must keep track of those, to
519: * adjust the costs appropriately in the operator table.
520: */
521: register int bc = 0;
522:
523: while( shp[s].sop == MANY )
524: {
525: bc += shp[s].scost;
526: if( smat( shp[s].sleft ) )
527: {
528: if( smat( shp[s].sright ) ) break;
529: else s = shp[s].sleft;
530: }
531: else s = shp[s].sright;
532: }
533: lshty.sha = -1;
534: rshty.sha = mkshp(s);
535: return( bc + shp[s].scost );
536: }
537:
538: lout1( n )
539: register n;
540: {
541: register int i;
542: while( n >= 0 && shp[n].sop == MANY )
543: {
544: lout1( shp[n].sleft );
545: n = shp[n].sright;
546: }
547: if( n < 0 )
548: return;
549: for( i=0; i<notb; ++i )
550: {
551: if( otb[i] == shp[n].sop ) return;
552: }
553: otb[notb++] = shp[n].sop;
554: }
555:
556: mkshp(s)
557: {
558: /* make a shape that yields s */
559: /* first, make s a MANY node */
560: register i;
561:
562: if( s < 0 ) return( s );
563: if( shp[s].sop == MANY ) i = s;
564: else {
565: /* look for a MANY node pointing to s */
566: for( i= NSTYSHPS; i>nmshp; --i ) {
567: if( shp[i].sright >= 0 ) continue;
568: if( shp[i].sleft == s ) goto foundit;
569: }
570: /* must make a MANY node */
571: i = bop( MANY, s, -1, 0 );
572: }
573:
574: /* now, make sure that i has a name, so it will be output */
575:
576: foundit: ;
577:
578: if( !shp[i].shname[0] ) {
579: strcpy( shp[i].shname, "mkshp" );
580: }
581: return(i);
582: }
583:
584: onebit(x)
585: register x;
586: {
587: /* return 1 if x has at most 1 bit on, 0 otherwise */
588: return( !(x&(x-1)) );
589: }
590:
591: output()
592: {
593: register OPTB *q;
594: register int j;
595:
596: if( lshty.ty == 0 ) lshty.ty = TANY;
597: if( rshty.ty == 0 ) rshty.ty = TANY;
598:
599: switch( op )
600: {
601:
602: case 0:
603: yyerror( "0 op" );
604:
605: case STAR:
606: case REG:
607: case UNARY MINUS:
608: case UNARY AND:
609: case FLD:
610: if( needs&(LSHARE|RSHARE) ) needs |= (LSHARE|RSHARE);
611: break;
612:
613: case ASSIGN:
614: case ASG PLUS:
615: case ASG MINUS:
616: case ASG MUL:
617: case ASG DIV:
618: case ASG MOD:
619: case ASG AND:
620: case ASG OR:
621: case ASG ER:
622: case ASG LS:
623: case ASG RS:
624: if( !(rewrite & (RNULL|RESC1|RESC2|RESC3|RRIGHT)) )
625: {
626: rewrite |= RLEFT;
627: }
628: }
629: if( !rewrite ) rewrite = RNULL;
630:
631: if( !onebit( rewrite & (RNULL|RLEFT|RRIGHT|RESC1|RESC2|RESC3) ) )
632: {
633: yyerror( "multiple results -- illegal (%o)", rewrite );
634: }
635: if( ((rewrite&RLEFT)&&(needs&LSHARE)) ||
636: ((rewrite&RRIGHT)&&(needs&RSHARE)) )
637: {
638: if( asstring[0] != 'Y' )
639: yyerror( "don't share on result side of tree" );
640: }
641: if( needs && (needs&(LSHARE|RSHARE)) == needs )
642: {
643: yyerror( "don't share without allocating something" );
644: }
645: checkout(asstring);
646:
647: q = &optb[opno];
648: if( opno >= NOPTB ) yyerror( "too many templates" );
649: q->line = lineno;
650: q->op = op;
651: q->tyop = tyop;
652: if( ophd[op]>=0 )
653: {
654: optb[optl[op]].nxop = opno;
655: optl[op] = opno;
656: }
657: else
658: {
659: optl[op] = ophd[op] = opno;
660: }
661: q->nxop = -1;
662: q->l = lshty;
663: q->r = rshty;
664: q->oneeds = needs;
665: q->orew = rewrite;
666: q->ocost = cost;
667: q->string = asstring;
668: q->olcount = lcount;
669: q->orcount = rcount;
670: /* now, take care of special cases */
671: if( optype(op) == LTYPE ) { /* leaf */
672: int s;
673: if( (s=q->r.sha) >= 0 && trivial(s) ) {
674: q->r.sha = -1; /* clobber any right shape */
675: }
676: }
677: else if( optype(op) == UTYPE ) {
678: if( q->r.sha >=0 ) {
679: /* someday, look for things below op */
680: /* for now, we get the cost wrong so back up */
681: }
682: }
683: ++opno;
684: }
685:
686: trivial( s ) {
687: /* is shape s a trivial match for op */
688: if( shp[s].sop == MANY ) {
689: if( shp[s].sright >= 0 ) {
690: return( 0 ); /* nontrivial */
691: }
692: s = shp[s].sleft;
693: }
694: if( shp[s].sop != op ) {
695: return( 0 );
696: }
697: if( shp[s].ssh ) {
698: return( 0 );
699: }
700: return( 1 ); /* ok to clobber */
701: }
702:
703: checkout(string)
704: char *string;
705: {
706: /* check out the string, looking at rewrite and needs */
707: /* look for {U,I,C,A}{L,R,1,2,3} and \n */
708: /* complain about:
709: *** 1, 2, 3 used, not allocated
710: *** shared side after \n after temp used
711: *** AL or AR used, w. side effect possible, more than once
712: */
713:
714: /* flagl and flagr are 1 if L and R legal, 0 if not, -1 if
715: /* they will be illegal after the next \n */
716:
717: register int flagl, flagr, prn, min, cond;
718: register char *s;
719:
720: flagl = flagr = 1;
721: cond = 0;
722:
723: for( s=string; *s; ++s )
724: {
725: switch( *s )
726: {
727:
728: case '\\':
729: ++s;
730: if( *s == '\\' ) ++s;
731: else if( *s == 'n' )
732: {
733: if( flagl<0 ) flagl=0;
734: if( flagr<0 ) flagr=0;
735: }
736: break;
737:
738: case 'Z':
739: ++s;
740: if( *s=='(' )
741: {
742: while( *++s != ')' ) {;}
743: }
744: break;
745:
746: case 'Y':
747: /* this string is asserted to be good; don't check */
748: return;
749:
750: case 'R':
751: case 'D':
752: /* conditional; a lot of stuff no longer is true */
753: cond = 1;
754: break;
755:
756: case 'A':
757: case 'C':
758: case 'U':
759: case 'I':
760: ++s;
761: if( *s == '-' )
762: {
763: ++s;
764: min = 1;
765: }
766: else min = 0;
767: if( *s == '(' )
768: {
769: ++s;
770: prn = 1;
771: }
772: else prn = 0;
773: switch( *s )
774: {
775:
776: case 'L':
777: if( !flagl && !cond )
778: {
779: yyerror( "illegal L just at \"%s\"",
780: s );
781: }
782: /* look for side-effects here */
783: if( !min && seff(lshty.sha)) flagl = 0;
784: break;
785:
786: case 'R':
787: if( !flagr && !cond )
788: {
789: yyerror( "illegal R just at \"%s\"",
790: s );
791: }
792: /* look for side-effects here */
793: if( !min && seff(rshty.sha)) flagr = 0;
794: break;
795:
796: case '1':
797: case '2':
798: case '3':
799: if( (*s - '0') > (needs&NCOUNT) )
800: {
801: yyerror( "reg %c used, not allocated",
802: *s );
803: }
804: if( (needs&LSHARE) && flagl ) flagl = -1;
805: if( (needs&RSHARE) && flagr ) flagr = -1;
806:
807: case '.':
808: break;
809:
810: default:
811: yyerror( "illegal qualifier just at \"%s\"",
812: s );
813: }
814: if( prn ) while( *s != ')' ) ++s;
815: }
816: }
817: }
818:
819: seff( s )
820: register s;
821: {
822: if( shp[s].sop == INCR || shp[s].sop == DECR ) return( 1 );
823: if( shp[s].sleft >= 0 && seff( shp[s].sleft ) ) return( 1 );
824: if( shp[s].sright >= 0 && seff( shp[s].sright ) ) return( 1 );
825: return( 0 );
826: }
827:
828: uop( o, a )
829: register o,a;
830: {
831: if( o == MUL ) o = STAR;
832: else if( o == MINUS ) o = UNARY MINUS;
833: else if( o == AND ) o = UNARY AND;
834: return( bop( o, a, -1, 0 ) );
835: }
836:
837: top( a, ty )
838: register a,ty;
839: {
840: /* build a type node over a */
841: /* must be done differently than uop, since types must be copied */
842: register STYSHP *p;
843:
844: if( a < 0 )
845: return( a );
846: checkit( a );
847: if( shp[a].sop == MANY )
848: {
849: register l, r;
850: l = shp[a].sleft;
851: r = shp[a].sright;
852: if( l >= 0 )
853: l = top( l, ty );
854: if( r >= 0 )
855: r = top( r, ty );
856: return( bop( MANY, l, r, 0 ) );
857: }
858: if( shp[a].ssh )
859: {
860: yyerror( "can't type a special node" );
861: }
862: shp[nshp] = shp[a];
863: shp[nshp].shname[0] = '\0';
864: shp[nshp].ssh = ty|SPTYPE;
865: shp[nshp].scset = 0;
866: nshp++;
867: checkit( nshp-1 );
868: return( nshp-1 );
869: }
870:
871: bop( o, a, b, cst )
872: register o, a, b, cst;
873: {
874: register STYSHP *p;
875: register int l, r, ret;
876:
877: checkit( a );
878: checkit( b );
879:
880: if( o != MANY )
881: {
882: while( shp[a].sop == MANY && shp[a].sright < 0 ) {
883: a = shp[a].sleft;
884: }
885: while( b >= 0 && shp[b].sop == MANY && shp[b].sright < 0 ) {
886: b = shp[b].sleft;
887: }
888: if( a>=0 && shp[a].sop == MANY )
889: {
890: /* distribute MANY nodes to top */
891: l = bop( o, shp[a].sleft, b, cst + shp[a].scost );
892: r = bop( o, shp[a].sright, b, cst + shp[a].scost );
893: return( bop( MANY, l, r, 0 ) );
894: }
895: if( b>=0 && shp[b].sop == MANY )
896: {
897: /* distribute MANY nodes to top */
898: l = bop( o, a, shp[b].sleft, cst + shp[b].scost );
899: r = bop( o, a, shp[b].sright, cst + shp[b].scost );
900: return( bop( MANY, l, r, 0 ) );
901: }
902: }
903:
904: if( o == MANY )
905: /* MANY nodes go at the end */
906: p = &shp[ ret = nmshp-- ];
907: else
908: p = &shp[ ret = nshp++ ];
909: if( nshp >= nmshp ) {
910: yyerror( "out of node space" );
911: exit( 1 );
912: }
913:
914: p->sop = o;
915: p->sleft = a;
916: p->sright =b;
917: p->scost = cst;
918: p->scset = 0;
919: p->ssh = 0;
920: p->shname[0] = '\0';
921: checkit( ret );
922: return( ret );
923: }
924:
925: int olist[] = { PLUS, MINUS, MUL, DIV, MOD, LS, RS, OR, ER, AND, -1 };
926:
927: struct nam
928: {
929: char *tntn;
930: int tnty;
931: };
932: #define NameV(x) "x", x /* name-value pairs */
933: struct nam Tnam[] = {
934: NameV(TANY),
935: NameV(TCHAR),
936: NameV(TSHORT),
937: NameV(TINT),
938: NameV(TLONG),
939: NameV(TFLOAT),
940: NameV(TDOUBLE),
941: NameV(TUCHAR),
942: NameV(TUSHORT),
943: NameV(TUNSIGNED),
944: NameV(TULONG),
945: NameV(TSTRUCT),
946: NameV(TPOINT),
947: NameV(TPOINT2),
948: NameV(TVOID),
949: NameV(urTINT),
950: NameV(urTUNSIGNED),
951: 0, 0,
952: };
953: struct nam Rwnam[] = {
954: NameV(RLEFT),
955: NameV(RRIGHT),
956: NameV(RESC1),
957: NameV(RESC2),
958: NameV(RESC3),
959: NameV(RESCC),
960: NameV(RNOP),
961: NameV(RNULL),
962: 0, 0
963: };
964: struct nam Ndnam[] = {
965: NameV(LSHARE),
966: NameV(RSHARE),
967: NameV(NPAIR),
968: NameV(LPREF),
969: NameV(RPREF),
970: 0, 0,
971: };
972: finished()
973: {
974: register STYSHP *p;
975: register OPTB *q, *q1;
976: register int i, j;
977:
978: /* terminate the templates */
979: printf( "# include \"mfile2.h\"\n\n" );
980:
981: /* chain binary ops together with the op= form */
982: for( i=0; (op=olist[i])>=0; ++i )
983: {
984: if( ophd[op]<0 )
985: ophd[op] = ophd[ASG op];
986: else
987: optb[optl[op]].nxop = ophd[ASG op];
988: }
989: if( ophd[STCALL]<0 )
990: ophd[STCALL] = ophd[CALL];
991: if( ophd[UNARY STCALL]<0 )
992: ophd[UNARY STCALL] = ophd[UNARY CALL];
993:
994: optbck();
995:
996: /* everything that gets used should be a MANY shape with name */
997: /* mkshp is called to cause this to be true */
998:
999: for( i=0; i<opno; ++i )
1000: {
1001: q = &optb[i];
1002: q->l.sha = mkshp(q->l.sha);
1003: q->r.sha = mkshp(q->r.sha);
1004: }
1005:
1006: /* avoid identical strings in optb[] by finding identical strings,
1007: giving them names and putting them at the front of table.c */
1008: for( i=0; i<opno; ++i )
1009: {
1010: q = &optb[i];
1011: q->struse = 1;
1012: q->strdef = -1;
1013: for(j = 0; j < i; j++)
1014: {
1015: q1 = &optb[j];
1016: if(!q1->struse)
1017: continue;
1018: if(strcmp(q->string,q1->string)==0)
1019: {
1020: q->strdef = j;
1021: q1->struse++;
1022: q->struse = 0;
1023: break;
1024: }
1025: }
1026: }
1027: for(i=0; i<opno; i++)
1028: {
1029: q = &optb[i];
1030: if(q->struse>1)
1031: {
1032: printf("static char Str%d[] = \"%s\";\n", i, q->string);
1033: q->struse = 0;
1034: q->strdef = i;
1035: }
1036: }
1037:
1038: /* set the ssh flags in shp, but don't print yet */
1039:
1040: for( j=0,i=NSTYSHPS-1; i>nmshp; --i ) {
1041: if( !shp[i].shname[0] ) continue;
1042: shp[i].ssh = j;
1043: j += manycount( i );
1044: ++j; /* count the null */
1045: }
1046:
1047: printf( "\n# define SHNL ((SHAPE *)0)\n" );
1048: printf( "# define S(x) (&shapes[x])\n" );
1049:
1050: printf( "\nSHAPE shapes[] = {\n" );
1051: for( i=0, p=shp; i<nshp; ++i,++p )
1052: {
1053: if( p->sop<0 )
1054: yyerror( "undefined shape: %.8s", p->shname );
1055: printf( "/*%4d */ ", i);
1056: printf( "%4d,\t",p->sop );
1057: saaddr(p->sleft);
1058: saaddr(p->sright);
1059: printf( "%#o,\t%d,", p->ssh, p->scost );
1060: if( p->shname[0] )
1061: printf( "\t/* %.8s */\n", p->shname );
1062: else
1063: putchar( '\n' );
1064: if(p->shname[0])
1065: chkdups(i);
1066: }
1067: printf( "\n};\n" );
1068:
1069: printf( "\n# define PSHNL ((SHAPE **)0)\n" );
1070: printf( "# define P(x) (&pshape[x])\n" );
1071:
1072: printf( "\nSHAPE *pshape[] = {\n" );
1073: for( j = 0, i = NSTYSHPS-1; i > nmshp; --i ) {
1074: if( !shp[i].shname[0] )
1075: continue;
1076: if( shp[i].ssh != j ) {
1077: fprintf( stderr, "shape %d, ssh=%d, j=%d\n",
1078: i, shp[i].ssh, j );
1079: }
1080: printf( "/*%4d %.8s */\t", j, shp[i].shname );
1081: j = manylist( i, j );
1082: printf( "SHNL,\n");
1083: ++j;
1084: }
1085: printf( "};\n" );
1086:
1087: printf( "struct optab table[] = {\n\n" );
1088: for( i=0; i<opno; ++i )
1089: {
1090: q = &optb[i];
1091: printf( "/* # %d, line %d */\n", i, q->line );
1092: prop( q->op );
1093: prnam( q->tyop, Tnam );
1094: if( q->nxop >= 0 )
1095: printf( "\t&table[%d],\n", q->nxop );
1096: else
1097: printf( "\t0,\n" );
1098:
1099: shpprint(q->l.sha, q->l.ty);
1100: shpprint(q->r.sha, q->r.ty);
1101: printf("\t\t");
1102: prnam(q->oneeds, Ndnam);
1103: printf("\t\t");
1104: prnam(q->orew, Rwnam);
1105: if(q->strdef>=0)
1106: printf("\t\tStr%d,\n", q->strdef);
1107: else
1108: printf("\t\t\"%s\",\n", q->string);
1109: printf("\t\t%d,%d,%d,%d,\n", q->ocost, q->olcount, q->orcount,
1110: q->line );
1111: }
1112: printf( "\n};\n" );
1113:
1114: printf( "OPTAB *ophead[] = {\n" );
1115:
1116: for( i=0; i<DSIZE; ++i )
1117: {
1118: if( ophd[i] < 0 ) printf( " 0,\n" );
1119: else printf( " &table[%d],\n", ophd[i] );
1120: }
1121: printf( "};\n" );
1122: }
1123:
1124: manycount( i )
1125: { /* count the descendents of shp[i] */
1126: int c;
1127:
1128: if( shp[i].sop == MANY ) {
1129: c = 0;
1130: if( shp[i].sleft >= 0 ) c += manycount( shp[i].sleft );
1131: if( shp[i].sright >= 0 ) c += manycount( shp[i].sright );
1132: return( c );
1133: }
1134: return( 1 );
1135: }
1136:
1137: manylist( i, j ) {
1138: /* put out a list of S(x) for shp[i], starting at j */
1139: /* first, put out CCODES and FREE */
1140: /* next, put out REG and TEMP */
1141: /* next, everything else */
1142: int k;
1143: int outcount = 0;
1144:
1145: if( i<0 ) return(j);
1146:
1147: setopsh( i ); /* set opsh[k] if op k is legal at head of i */
1148: if( opsh[FREE] ) {
1149: j = manyop( i, j, FREE, &outcount );
1150: opsh[FREE] = 0;
1151: }
1152: if( opsh[CCODES] ) {
1153: j = manyop( i, j, CCODES, &outcount );
1154: opsh[CCODES] = 0;
1155: }
1156: if( opsh[REG] ) {
1157: j = manyop( i, j, REG, &outcount );
1158: opsh[REG] = 0;
1159: }
1160: if( opsh[TEMP] ) {
1161: j = manyop( i, j, TEMP, &outcount );
1162: opsh[TEMP] = 0;
1163: }
1164: for( k=0; k<DSIZE; ++k ) {
1165: if( opsh[k] ) {
1166: j = manyop( i, j, k, &outcount );
1167: opsh[k] = 0;
1168: }
1169: }
1170: return( j );
1171: }
1172:
1173: manyop( i, j, o, cp )
1174: int *cp;
1175: {
1176: /* put out a list of S(x) for shapes matching op */
1177:
1178: if( i<0 ) return( j );
1179: if( shp[i].sop == MANY ) {
1180: j = manyop( shp[i].sleft, j, o, cp );
1181: return( manyop( shp[i].sright, j, o, cp ) );
1182: }
1183: if( shp[i].sop == o ) {
1184: printf( "S(%d), ", i );
1185: if( !((++*cp)&07) ) printf( "\n\t\t" );
1186: return( j+1 );
1187: }
1188: return( j );
1189: }
1190:
1191: setopsh( i ) {
1192: /* set opsh[k] to 1 for every op appearing in shp[i] */
1193: int s;
1194:
1195: if( i<0 ) return;
1196: s = shp[i].sop;
1197:
1198: if( s == MANY ) {
1199: setopsh( shp[i].sleft );
1200: setopsh( shp[i].sright );
1201: }
1202: else opsh[s] = 1;
1203: }
1204:
1205: saaddr(sp)
1206: register sp;
1207: {
1208: if( sp < 0 ) printf( "SHNL,\t" );
1209: else printf( "S(%d),\t", sp );
1210: }
1211:
1212:
1213: int nodcnt;
1214: int treecnt;
1215: chkdups(ii)
1216: register ii;
1217: {
1218: treecnt = nodcnt = 0;
1219: chkdup1(ii);
1220: if(treecnt!=nodcnt)
1221: {
1222: fprintf(stderr,"DUPLICATE SHAPES IN TREE %s\n",shp[ii].shname);
1223: prtree("T",ii);
1224: }
1225: clrcnt(ii);
1226: }
1227: chkdup1(nn)
1228: register nn;
1229: {
1230: register STYSHP *p;
1231:
1232: p = &shp[nn];
1233: if((p->sleft >= 0) && (p->sop==MANY)) chkdup1(p->sleft);
1234: if((p->sright >= 0) && (p->sop==MANY)) chkdup1(p->sright);
1235: p->scnt++;
1236: nodcnt++;
1237: treecnt += p->scnt;
1238: }
1239: clrcnt(nn)
1240: register nn;
1241: {
1242: register STYSHP *p;
1243:
1244: p = &shp[nn];
1245: if(p->sleft >= 0) clrcnt(p->sleft);
1246: if(p->sright >= 0) clrcnt(p->sright);
1247: p->scnt = 0;
1248: }
1249:
1250: prtree(str,ii)
1251: register ii;
1252: char *str;
1253: {
1254: register STYSHP *p;
1255: p = &shp[ii];
1256: fprintf(stderr,"%s.%d = %d",str,ii,p->scnt);
1257: if(p->shname[0]) fprintf(stderr," /* %s */",p->shname);
1258: fprintf(stderr,"\n");
1259: if(p->sright>=0) prtree("R",p->sright);
1260: if(p->sleft>=0) prtree("L",p->sleft);
1261: }
1262: shpprint(sha, ty)
1263: register sha,ty;
1264: {
1265: if( sha < 0 ) printf( "\tPSHNL,\t");
1266: else printf( "\tP(%d),\t", shp[sha].ssh );
1267: prnam( ty, Tnam );
1268: }
1269:
1270: prnam(ty,src)
1271: register struct nam *src;
1272: register ty;
1273: {
1274: register int ii,jj;
1275: register flag = 0;
1276: register struct nam *tn;
1277:
1278: if(!ty)
1279: {
1280: printf("0x0,\n");
1281: return;
1282: }
1283: for(tn = src; tn->tntn; tn++)
1284: if( tn->tnty == ty )
1285: {
1286: printf( "%s,\n", tn->tntn );
1287: return;
1288: }
1289: for(ii = 0; ; ii++)
1290: {
1291: if((jj = (01<<ii))>ty)
1292: {
1293: printf(",\n");
1294: return;
1295: }
1296: if(!(jj & ty))
1297: continue;
1298: for(tn = src; tn->tntn; tn++)
1299: if(tn->tnty==jj)
1300: break;
1301: if(flag++)
1302: printf("|");
1303: if(tn->tntn)
1304: printf("%s",tn->tntn);
1305: else
1306: printf("%#o",jj);
1307: }
1308: }
1309:
1310: static char name[100]; /* had better be long enough */
1311:
1312: yylex()
1313: {
1314: register int c, i;
1315:
1316: for(;;)
1317: {
1318:
1319: c = getchar();
1320: if( c<0 ) return( -1 );
1321: switch( c )
1322: {
1323:
1324: case '\n':
1325: ++lineno;
1326: case ' ':
1327: case '\b':
1328: case '\f':
1329: case '\v':
1330: case '\t':
1331: continue;
1332:
1333: case '<':
1334: case '>':
1335: case '+':
1336: case '-':
1337: case '=':
1338: case '*':
1339: case '%':
1340: case '/':
1341: case '&':
1342: case '|':
1343: case '^':
1344: case '!':
1345: name[0] = c;
1346: name[1] = getchar();
1347: name[2] = '\0';
1348: if( oplook() )
1349: {
1350: if( yylval.ival == LS || yylval.ival == RS )
1351: {
1352: if( (c=getchar()) == '=' )
1353: yylval.ival = ASG yylval.ival;
1354: else ungetc( c, stdin );
1355: }
1356: return( OP );
1357: }
1358: ungetc( name[1], stdin );
1359: name[1] = '\0';
1360: if( oplook() ) return( OP );
1361: yyerror( "cannot deal with %c", name[0] );
1362: return( OP );
1363:
1364: case '~':
1365: yylval.ival = COMPL;
1366: return( OP );
1367:
1368: case '"':
1369: string = pstring;
1370: while( pstring < &strng[NSTRING-2] )
1371: {
1372: switch( c = getchar() ) {
1373: case '\t':
1374: *pstring++ = '\\';
1375: *pstring++ = 't';
1376: break;
1377: case '\n':
1378: *pstring++ = '\\';
1379: *pstring++ = 'n';
1380: ++lineno;
1381: break;
1382: case '\\': /* escape */
1383: *pstring++ = '\\';
1384: c = getchar();
1385: if( c == '\n' )
1386: ++lineno;
1387: else if( c<0 )
1388: yyerror( "missing \"" );
1389: else if( isalpha(c) && isupper(c) )
1390: *pstring++ = '\\';
1391: *pstring++ = c;
1392: break;
1393: case '"':
1394: *pstring++ = '\0';
1395: goto eos;
1396: default:
1397: if( c<0 )
1398: yyerror( "missing \"" );
1399: *pstring++ = c;
1400: }
1401: }
1402: eos:
1403: if( pstring >= &strng[NSTRING] )
1404: yyerror( "s_table overflow" );
1405: yylval.str = string;
1406: return( STR );
1407:
1408: case '\'':
1409: for( i = 0; i < sizeof name - 1; ++i )
1410: {
1411: c = getchar();
1412: if( c == '\'' ) break;
1413: if( c == '\n' ) yyerror( "missing '" );
1414: name[i] = c;
1415: }
1416: name[i] = '\0';
1417: if( oplook() ) return( OP );
1418: yyerror( "bad op name: '%s'", name );
1419:
1420: case '[':
1421: for( i = 0; i < sizeof name - 1; ++i )
1422: {
1423: c = getchar();
1424: if( c == ']' ) break;
1425: if( c == '\n' ) yyerror( "missing ]" );
1426: name[i] = c;
1427: }
1428: name[i] = '\0';
1429: yylval.ival = tystr(name);
1430: return( STYPE );
1431:
1432: case '#': /* comment */
1433: while( (c = getchar()) != '\n' )
1434: {
1435: if( c < 0 ) yyerror( "unexpected EOF" );
1436: }
1437: ++lineno;
1438: continue;
1439:
1440: case '$':
1441: c = getchar();
1442: if( isdigit(c) )
1443: {
1444: yylval.ival = c-'0';
1445: return( RREG );
1446: }
1447: switch( c )
1448: {
1449: case '[': return( LPRF );
1450: case ']': return( RPRF );
1451: case '<': return( LSHR );
1452: case '>': return( RSHR );
1453: case 'L': return( LRES );
1454: case 'R': return( RRES );
1455: case 'P': return( PNEED );
1456: case 'C': return( GOODCC );
1457: case 'N': return( NOVAL );
1458: case 'r': return( RCOUNT );
1459: case 'l': return( LCOUNT );
1460: case 'A': yylval.ival = NRGS;
1461: return( DIG );
1462: }
1463: yyerror( "$%c illegal", c );
1464:
1465: default:
1466: if( isdigit(c) )
1467: {
1468: yylval.ival = c-'0';
1469: return( DIG );
1470: }
1471: if( isalpha(c) )
1472: {
1473: /* collect the name */
1474: int i = 1;
1475: name[0] = c;
1476: while( isalpha( (c=getchar()) ) || isdigit(c) )
1477: {
1478: name[i++] = c;
1479: }
1480: name[i] = '\0';
1481: ungetc( c, stdin );
1482: return( lookup() );
1483: }
1484: return( c );
1485: }
1486: }
1487: }
1488:
1489: struct nlist {
1490: char *shop;
1491: int vop;
1492: } ot[] = {
1493:
1494: "++", INCR,
1495: "+", PLUS,
1496: "--", DECR,
1497: "-", MINUS,
1498: "*", MUL,
1499: "%", MOD,
1500: "/", DIV,
1501: "&", AND,
1502: "^", ER,
1503: "!=", NE,
1504: "==", EQ,
1505: "UMINUS", UNARY MINUS,
1506: "UAND", UNARY AND,
1507: "STAR", STAR,
1508: "+=", ASG PLUS,
1509: "-=", ASG MINUS,
1510: "*=", ASG MUL,
1511: "/=", ASG DIV,
1512: "%=", ASG MOD,
1513: "&=", ASG AND,
1514: "|=", ASG OR,
1515: "|", OR,
1516: "^=", ASG ER,
1517: "=", ASSIGN,
1518: "<", LT,
1519: "<=", LE,
1520: "<<", LS,
1521: ">", GT,
1522: ">=", GE,
1523: ">>", RS,
1524: "FLD", FLD,
1525: "CMP", CMP,
1526: "COMOP", COMOP,
1527: "CM", CM,
1528: "GENLAB", GENLAB,
1529: "GENUBR", GENUBR,
1530: "GENBR", GENBR,
1531: "ARG", FUNARG,
1532: "STARG", STARG,
1533: "STASG", STASG,
1534: "INIT", INIT,
1535: "GOTO", GOTO,
1536: "CALL", CALL,
1537: "UCALL", UNARY CALL,
1538: "STCALL", STCALL,
1539: "USTCALL", UNARY STCALL,
1540: "CONV", CONV,
1541: "PDIV", PDIV,
1542: "PMUL", PMUL,
1543: "REG", REG,
1544: "CON", ICON,
1545: "TEMP", TEMP,
1546: "AUTO", VAUTO,
1547: "PARAM", VPARAM,
1548: "NAME", NAME,
1549: "RNODE", RNODE,
1550: "SNODE", SNODE,
1551: "QNODE", QNODE,
1552: "CC", CCODES,
1553: "FREE", FREE,
1554: "UOP0", UOP0,
1555: "UOP1", UOP1,
1556: "UOP2", UOP2,
1557: "UOP3", UOP3,
1558: "UOP4", UOP4,
1559: "UOP5", UOP5,
1560: "UOP6", UOP6,
1561: "UOP7", UOP7,
1562: "UOP8", UOP8,
1563: "UOP9", UOP9,
1564: "", -1 };
1565:
1566: oplook()
1567: {
1568: /* look up the first n chars of name in the above table */
1569: /* return 1 if it is an op, after setting yylval */
1570: register int i;
1571: for( i=0; ot[i].vop >= 0; ++i )
1572: {
1573: if( !strcmp( name, ot[i].shop ) )
1574: {
1575: yylval.ival = ot[i].vop;
1576: return( 1 );
1577: }
1578: }
1579: return( 0 );
1580: }
1581:
1582: tystr( p )
1583: register char *p; /* pointer to name */
1584: {
1585: register i;
1586:
1587: /* lookup the types in name */
1588: if( !*p )
1589: return( TANY );
1590: else
1591: i = 0;
1592: for(;;)
1593: {
1594: switch( *p++ )
1595: {
1596: case '\0':
1597: return( i );
1598:
1599: case 'c':
1600: i |= TCHAR;
1601: case ' ':
1602: case ',':
1603: continue;
1604:
1605: case 's':
1606: i |= TSHORT;
1607: continue;
1608:
1609: case 'i':
1610: i |= TINT;
1611: continue;
1612:
1613: case 'l':
1614: i |= TLONG;
1615: continue;
1616:
1617: case 'f':
1618: i |= TFLOAT;
1619: continue;
1620:
1621: case 'd':
1622: i |= TDOUBLE;
1623: continue;
1624:
1625: case 'P':
1626: i |= TPOINT2;
1627: continue;
1628:
1629: case 'p':
1630: i |= TPOINT;
1631: continue;
1632:
1633: case 't':
1634: i |= TSTRUCT;
1635: continue;
1636:
1637: case 'v':
1638: /* later..
1639: i |= TVOID;
1640: */
1641: continue;
1642:
1643: case 'u':
1644: switch( *p )
1645: {
1646: case 'i': i |= TUNSIGNED; break;
1647: case 's': i |= TUSHORT; break;
1648: case 'c': i |= TUCHAR; break;
1649: case 'l': i |= TULONG; break;
1650: default: yyerror( "bad u%c type", *p );
1651: }
1652: ++p;
1653: continue;
1654:
1655: default:
1656: yyerror( "illegal type: %c", p[-1] );
1657: }
1658: }
1659: }
1660:
1661: struct nlist resw[] = {
1662: NameV(DCOST),
1663: NameV(SHAPES),
1664: NameV(OPCODES),
1665: NameV(USERCOST),
1666: NameV(CONVAL),
1667: NameV(NCONVAL),
1668: NameV(POSRANGE),
1669: NameV(SGRANGE),
1670: NameV(NONAME),
1671: "", -1,
1672: };
1673:
1674: lookup()
1675: {
1676: /* look up the shape name in name, and return the index */
1677: register STYSHP *p;
1678: register int i;
1679: for( i=0; resw[i].vop >= 0; ++i )
1680: {
1681: if( !strcmp( name, resw[i].shop ) ) return( resw[i].vop );
1682: }
1683: for( i=NSTYSHPS-1, p= &shp[NSTYSHPS-1]; i>nmshp; --i,--p )
1684: {
1685: if( !strncmp( name, p->shname, 8 ) )
1686: {
1687: /* match */
1688: yylval.ival = i;
1689: return( NM );
1690: }
1691: }
1692: /* new entry */
1693: strncpy( p->shname, name, 8 );
1694: p->scset = p->ssh = p->scost = 0;
1695: p->sleft = p->sright = -1;
1696: p->sop = -1;
1697: yylval.ival = nmshp--;
1698: if( nmshp <= nshp ) {
1699: yyerror( "out of node space" );
1700: exit( 1 );
1701: }
1702: return( NM );
1703: }
1704:
1705: setcost ( sn, cst )
1706: register int sn,cst;
1707: {
1708: /* set costs for shape at all reference points.
1709: /* reference points all are just below MANY ops
1710: */
1711: if ( sn < 0 )
1712: return;
1713: if ( shp[sn].sop == MANY )
1714: {
1715: setcost( shp[sn].sleft, cst );
1716: setcost( shp[sn].sright, cst );
1717: }
1718: else if ( was_cost )
1719: {
1720: if ( shp[sn].scset )
1721: {
1722: if ( shp[sn].scost == cst )
1723: return;
1724: yyerror( "Inconsistent cost values for shared shape" );
1725: }
1726: else
1727: {
1728: shp[sn].scost = cst;
1729: shp[sn].scset = 1;
1730: }
1731: }
1732: else
1733: {
1734: shp[sn].scset = 1;
1735: }
1736: }
1737:
1738: sharecost ( sn, cst )
1739: register int sn,cst;
1740: {
1741: if ( sn == nshp - 1 ) /* quick opt. there is only one choice */
1742: {
1743: shp[sn].scost = cst;
1744: shp[sn].scset = 1;
1745: return(sn);
1746: }
1747: /* if ( cst == 0 )
1748: /* return( sn );
1749: */
1750:
1751: setcost(sn, cst);
1752: return (sn);
1753: /* if (nshp >= NSTYSHPS)
1754: /* yyerror("too many shapes");
1755: /* shp[nshp] = shp[sn];
1756: /* shp[nshp].scost += cst;
1757: /* nshp++;
1758: /* checkit( nshp-1 );
1759: /* return( nshp-1 );
1760: */
1761: }
1762:
1763: uopcost (o, a)
1764: register int o,a;
1765: {
1766: switch(o)
1767: {
1768: default:
1769: case MUL:
1770: case AND: yyerror("Illegal unary cost operator");
1771: return(0);
1772: case MINUS:
1773: return(-a);
1774: }
1775: }
1776:
1777: bopcost (o, a, b)
1778: register int o,a,b;
1779: {
1780: switch(o)
1781: {
1782: case INCR:
1783: case PLUS: return(a+b);
1784: case DECR:
1785: case MINUS: return(a-b);
1786: case MUL: return(a*b);
1787: case DIV: return(a/b);
1788: case MOD: return(a%b);
1789: case LS: return(a>>b);
1790: case RS: return(a<<b);
1791: case OR: return(a|b);
1792: case ER: return(a^b);
1793: case AND: return(a&b);
1794: case LT: return(a<b);
1795: case GT: return(a>b);
1796: case LE: return(a<=b);
1797: case GE: return(a>=b);
1798: case NE: return(a!=b);
1799: case EQ: return(a==b);
1800: default: yyerror("Illegal binary operator");
1801: return(0);
1802: }
1803: }
1804:
1805: /* print operator name
1806: */
1807: static
1808: prop( op )
1809: register int op;
1810: {
1811: register struct nam *np;
1812: static struct nam Opnam[] = {
1813: NameV(INCR),
1814: NameV(PLUS),
1815: NameV(DECR),
1816: NameV(MINUS),
1817: NameV(MUL),
1818: NameV(MOD),
1819: NameV(DIV),
1820: NameV(AND),
1821: NameV(ER),
1822: NameV(NE),
1823: NameV(EQ),
1824: NameV(UNARY MINUS),
1825: NameV(UNARY AND),
1826: NameV(STAR),
1827: NameV(ASG PLUS),
1828: NameV(ASG MINUS),
1829: NameV(ASG MUL),
1830: NameV(ASG DIV),
1831: NameV(ASG MOD),
1832: NameV(ASG AND),
1833: NameV(ASG OR),
1834: NameV(OR),
1835: NameV(ASG ER),
1836: NameV(ASSIGN),
1837: NameV(LT),
1838: NameV(LE),
1839: NameV(LS),
1840: NameV(GT),
1841: NameV(GE),
1842: NameV(RS),
1843: NameV(FLD),
1844: NameV(CMP),
1845: NameV(COMOP),
1846: NameV(CM),
1847: NameV(GENLAB),
1848: NameV(GENUBR),
1849: NameV(GENBR),
1850: NameV(FUNARG),
1851: NameV(STARG),
1852: NameV(STASG),
1853: NameV(INIT),
1854: NameV(GOTO),
1855: NameV(CALL),
1856: NameV(UNARY CALL),
1857: NameV(STCALL),
1858: NameV(UNARY STCALL),
1859: NameV(CONV),
1860: NameV(PDIV),
1861: NameV(PMUL),
1862: NameV(REG),
1863: NameV(ICON),
1864: NameV(TEMP),
1865: NameV(VAUTO),
1866: NameV(VPARAM),
1867: NameV(NAME),
1868: NameV(RNODE),
1869: NameV(SNODE),
1870: NameV(QNODE),
1871: NameV(CCODES),
1872: NameV(FREE),
1873: 0, 0,
1874: };
1875: for( np = Opnam; np->tnty; np++ )
1876: {
1877: if( op == np->tnty )
1878: {
1879: printf( "%s,", np->tntn );
1880: return;
1881: }
1882: }
1883: printf( "%d,", op );
1884: }
1885:
1886:
1887: /*
1888: check the op table for duplicate or partially duplicate templates
1889: */
1890: static
1891: optbck()
1892: {
1893: #define EqOptb(a) (q->a == q1->a)
1894: register int i;
1895: register int j;
1896: register OPTB *q;
1897: register OPTB *q1;
1898:
1899: for( i = 0; i < opno; i++ )
1900: {
1901: q = &optb[i];
1902: for( j = 0; j < i; j++ )
1903: {
1904: q1 = &optb[j];
1905: if(
1906: EqOptb(op) &&
1907: EqOptb(l.ty) &&
1908: EqOptb(r.ty) &&
1909: EqOptb(orew) &&
1910: EqOptb(oneeds) &&
1911: shapeshr(q->l.sha, q1->l.sha) &&
1912: shapeshr(q->r.sha, q1->r.sha)
1913: )
1914: {
1915: fprintf( stderr,
1916: "line %d may be covered by line %d\n",
1917: q->line, q1->line );
1918: break;
1919: }
1920: }
1921: }
1922: }
1923:
1924:
1925: /* do the shape trees starting at s1 and s2 share any elements?
1926: */
1927: static
1928: shapeshr( s1, s2 )
1929: register int s1; /* indexes into shape table */
1930: register int s2;
1931: {
1932: register int i1;
1933:
1934: for( i1 = s1; shp[i1].sleft >= 0; i1 = shp[i1].sleft )
1935: {
1936: if( i1 == s2 || shp[i1].sright == s2 )
1937: return 1;
1938: }
1939: return 0;
1940: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.