|
|
1.1 root 1: # include "pass2.h"
2:
3: # ifdef WCARD1
4: # ifdef WCARD2
5: # define NOINDIRECT
6: # endif
7: # endif
8:
9: extern vdebug;
10:
11: int fldsz, fldshf;
12:
13: static int mamask[] = { /* masks for matching dope with shapes */
14: SIMPFLG, /* OPSIMP */
15: SIMPFLG|ASGFLG, /* ASG OPSIMP */
16: COMMFLG, /* OPCOMM */
17: COMMFLG|ASGFLG, /* ASG OPCOMM */
18: MULFLG, /* OPMUL */
19: MULFLG|ASGFLG, /* ASG OPMUL */
20: DIVFLG, /* OPDIV */
21: DIVFLG|ASGFLG, /* ASG OPDIV */
22: UTYPE, /* OPUNARY */
23: TYFLG, /* ASG OPUNARY is senseless */
24: LTYPE, /* OPLEAF */
25: TYFLG, /* ASG OPLEAF is senseless */
26: 0, /* OPANY */
27: ASGOPFLG|ASGFLG, /* ASG OPANY */
28: LOGFLG, /* OPLOG */
29: TYFLG, /* ASG OPLOG is senseless */
30: FLOFLG, /* OPFLOAT */
31: FLOFLG|ASGFLG, /* ASG OPFLOAT */
32: SHFFLG, /* OPSHFT */
33: SHFFLG|ASGFLG, /* ASG OPSHIFT */
34: SPFLG, /* OPLTYPE */
35: TYFLG, /* ASG OPLTYPE is senseless */
36: };
37:
38: int sdebug = 0;
39:
40: tshape( p, shape ) NODE *p; {
41: /* return true if shape is appropriate for the node p
42: side effect for SFLD is to set up fldsz,etc */
43: register int o, mask;
44:
45: o = p->in.op;
46:
47: # ifndef BUG3
48: if( sdebug ){
49: printf( "tshape( %o, %o), op = %d\n", p, shape, o );
50: }
51: # endif
52:
53: if( shape & SPECIAL ){
54:
55: switch( shape ){
56:
57: case SZERO:
58: case SONE:
59: case SMONE:
60: case SSCON:
61: case SCCON:
62: if( o != ICON || p->in.name[0] ) return(0);
63: if( p->tn.lval == 0 && shape == SZERO ) return(1);
64: else if( p->tn.lval == 1 && shape == SONE ) return(1);
65: else if( p->tn.lval == -1 && shape == SMONE ) return(1);
66: else if( p->tn.lval > -129 && p->tn.lval < 128 && shape == SCCON ) return(1);
67: else if( p->tn.lval > -32769 && p->tn.lval < 32768 && shape == SSCON ) return(1);
68: else return(0);
69:
70: case SSOREG: /* non-indexed OREG */
71: if( o == OREG && !R2TEST(p->tn.rval) ) return(1);
72: else return(0);
73:
74: default:
75: # ifdef MULTILEVEL
76: if( shape & MULTILEVEL )
77: return( mlmatch(p,shape,0) );
78: else
79: # endif
80: return( special( p, shape ) );
81: }
82: }
83:
84: if( shape & SANY ) return(1);
85:
86: if( (shape&INTEMP) && shtemp(p) ) return(1);
87:
88: if( (shape&SWADD) && (o==NAME||o==OREG) ){
89: if( BYTEOFF(p->tn.lval) ) return(0);
90: }
91:
92: # ifdef WCARD1
93: if( shape & WCARD1 )
94: return( wcard1(p) & shape );
95: # endif
96:
97: # ifdef WCARD2
98: if( shape & WCARD2 )
99: return( wcard2(p) & shape );
100: # endif
101: switch( o ){
102:
103: case NAME:
104: return( shape&SNAME );
105: case ICON:
106: mask = SCON;
107: return( shape & mask );
108:
109: case FLD:
110: if( shape & SFLD ){
111: if( !flshape( p->in.left ) ) return(0);
112: /* it is a FIELD shape; make side-effects */
113: o = p->tn.rval;
114: fldsz = UPKFSZ(o);
115: # ifdef RTOLBYTES
116: fldshf = UPKFOFF(o);
117: # else
118: fldshf = SZINT - fldsz - UPKFOFF(o);
119: # endif
120: return(1);
121: }
122: return(0);
123:
124: case CCODES:
125: return( shape&SCC );
126:
127: case REG:
128: /* distinctions:
129: SAREG any scalar register
130: STAREG any temporary scalar register
131: SBREG any lvalue (index) register
132: STBREG any temporary lvalue register
133: */
134: mask = isbreg( p->tn.rval ) ? SBREG : SAREG;
135: if( istreg( p->tn.rval ) && busy[p->tn.rval]<=1 ) mask |= mask==SAREG ? STAREG : STBREG;
136: return( shape & mask );
137:
138: case OREG:
139: return( shape & SOREG );
140:
141: # ifndef NOINDIRECT
142: case UNARY MUL:
143: /* return STARNM or STARREG or 0 */
144: return( shumul(p->in.left) & shape );
145: # endif
146:
147: }
148:
149: return(0);
150: }
151:
152: int tdebug = 0;
153:
154: ttype( t, tword ) TWORD t; {
155: /* does the type t match tword */
156:
157: if( tword & TANY ) return(1);
158:
159: if( t == UNDEF ) t=INT; /* void functions eased thru tables */
160: # ifndef BUG3
161: if( tdebug ){
162: printf( "ttype( %o, %o )\n", t, tword );
163: }
164: # endif
165: if( ISPTR(t) && (tword&TPTRTO) ) {
166: do {
167: t = DECREF(t);
168: } while ( ISARY(t) );
169: /* arrays that are left are usually only
170: in structure references... */
171: return( ttype( t, tword&(~TPTRTO) ) );
172: }
173: if( t != BTYPE(t) ) return( tword & TPOINT ); /* TPOINT means not simple! */
174: if( tword & TPTRTO ) return(0);
175:
176: switch( t ){
177:
178: case CHAR:
179: return( tword & TCHAR );
180: case SHORT:
181: return( tword & TSHORT );
182: case STRTY:
183: case UNIONTY:
184: return( tword & TSTRUCT );
185: case INT:
186: return( tword & TINT );
187: case UNSIGNED:
188: return( tword & TUNSIGNED );
189: case USHORT:
190: return( tword & TUSHORT );
191: case UCHAR:
192: return( tword & TUCHAR );
193: case ULONG:
194: return( tword & TULONG );
195: /*
196: case LONG:
197: return( tword & TLONG );
198: */
199: case FLOAT:
200: return( tword & TFLOAT );
201: case DOUBLE:
202: return( tword & TDOUBLE );
203: }
204:
205: return(0);
206: }
207:
208: struct optab *rwtable;
209:
210: struct optab *opptr[DSIZE];
211:
212: setrew(){
213: /* set rwtable to first value which allows rewrite */
214: register struct optab *q;
215: register int i;
216:
217: # ifdef MULTILEVEL
218: /* also initialize multi-level tree links */
219: mlinit();
220: # endif
221:
222: for( q = table; q->op != FREE; ++q ){
223: if( q->needs == REWRITE ){
224: rwtable = q;
225: goto more;
226: }
227: }
228: cerror( "bad setrew" );
229:
230:
231: more:
232: for( i=0; i<DSIZE; ++i ){
233: if( dope[i] ){ /* there is an op... */
234: for( q=table; q->op != FREE; ++q ){
235: /* beware; things like LTYPE that match
236: multiple things in the tree must
237: not try to look at the NIL at this
238: stage of things! Put something else
239: first in table.c */
240: /* at one point, the operator matching was 15% of the
241: total comile time; thus, the function
242: call that was here was removed...
243: */
244:
245: if( q->op < OPSIMP ){
246: if( q->op==i ) break;
247: }
248: else {
249: register int opmtemp;
250: if((opmtemp=mamask[q->op - OPSIMP])&SPFLG){
251: if( i==NAME || i==ICON || i==OREG ) break;
252: else if( shltype( i, NIL ) ) break;
253: }
254: else if( (dope[i]&(opmtemp|ASGFLG)) == opmtemp ) break;
255: }
256: }
257: opptr[i] = q;
258: }
259: }
260: }
261:
262: match( p, cookie ) NODE *p; {
263: /* called by: order, gencall
264: look for match in table and generate code if found unless
265: entry specified REWRITE.
266: returns MDONE, MNOPE, or rewrite specification from table */
267:
268: register struct optab *q;
269: register NODE *r;
270:
271: rcount();
272: if( cookie == FORREW ) q = rwtable;
273: else q = opptr[p->in.op];
274:
275: for( ; q->op != FREE; ++q ){
276:
277: /* at one point the call that was here was over 15% of the total time;
278: thus the function call was expanded inline */
279: if( q->op < OPSIMP ){
280: if( q->op!=p->in.op ) continue;
281: }
282: else {
283: register int opmtemp;
284: if((opmtemp=mamask[q->op - OPSIMP])&SPFLG){
285: if( p->in.op!=NAME && p->in.op!=ICON && p->in.op!= OREG &&
286: ! shltype( p->in.op, p ) ) continue;
287: }
288: else if( (dope[p->in.op]&(opmtemp|ASGFLG)) != opmtemp ) continue;
289: }
290:
291: if( !(q->visit & cookie ) ) continue;
292: r = getlr( p, 'L' ); /* see if left child matches */
293: if( !tshape( r, q->lshape ) ) continue;
294: if( !ttype( r->in.type, q->ltype ) ) continue;
295: r = getlr( p, 'R' ); /* see if right child matches */
296: if( !tshape( r, q->rshape ) ) continue;
297: if( !ttype( r->in.type, q->rtype ) ) continue;
298:
299: /* REWRITE means no code from this match but go ahead
300: and rewrite node to help future match */
301: if( q->needs & REWRITE ) return( q->rewrite );
302: if( !allo( p, q ) ) continue; /* if can't generate code, skip entry */
303:
304: /* resources are available */
305:
306: expand( p, cookie, q->cstring ); /* generate code */
307: reclaim( p, q->rewrite, cookie );
308:
309: return(MDONE);
310:
311: }
312:
313: return(MNOPE);
314: }
315:
316: int rtyflg = 0;
317:
318: expand( p, cookie, cp ) NODE *p; register char *cp; {
319: /* generate code by interpreting table entry */
320:
321: register char c;
322: CONSZ val;
323:
324: rtyflg = 0;
325:
326: for( ; *cp; ++cp ){
327: switch( *cp ){
328:
329: default:
330: PUTCHAR( *cp );
331: continue; /* this is the usual case... */
332:
333: case 'T':
334: /* rewrite register type is suppressed */
335: rtyflg = 1;
336: continue;
337:
338: case 'Z': /* special machine dependent operations */
339: # ifdef NEWZZZ
340: switch( c = *++cp ) {
341:
342: case '1':
343: case '2':
344: case '3':
345: case 'R':
346: case 'L': /* get down first */
347: zzzcode( getlr( p, c ), *++cp );
348: break;
349: default: /* normal zzzcode processing otherwise */
350: zzzcode( p, c );
351: break;
352: }
353: # else
354: zzzcode( p, *++cp );
355: # endif
356: continue;
357:
358: case 'F': /* this line deleted if FOREFF is active */
359: if( cookie & FOREFF ) while( *++cp != '\n' ) ; /* VOID */
360: continue;
361:
362: case 'S': /* field size */
363: printf( "%d", fldsz );
364: continue;
365:
366: case 'H': /* field shift */
367: printf( "%d", fldshf );
368: continue;
369:
370: case 'M': /* field mask */
371: case 'N': /* complement of field mask */
372: val = 1;
373: val <<= fldsz;
374: --val;
375: val <<= fldshf;
376: adrcon( *cp=='M' ? val : ~val );
377: continue;
378:
379: case 'L': /* output special label field */
380: printf( "%d", p->bn.label );
381: continue;
382:
383: case 'O': /* opcode string */
384: hopcode( *++cp, p->in.op );
385: continue;
386:
387: case 'B': /* byte offset in word */
388: val = getlr(p,*++cp)->tn.lval;
389: val = BYTEOFF(val);
390: printf( CONFMT, val );
391: continue;
392:
393: case 'C': /* for constant value only */
394: conput( getlr( p, *++cp ) );
395: continue;
396:
397: case 'I': /* in instruction */
398: insput( getlr( p, *++cp ) );
399: continue;
400:
401: case 'A': /* address of */
402: adrput( getlr( p, *++cp ) );
403: continue;
404:
405: case 'U': /* for upper half of address, only */
406: upput( getlr( p, *++cp ) );
407: continue;
408:
409: }
410:
411: }
412:
413: }
414:
415: NODE *
416: getlr( p, c ) NODE *p; {
417:
418: /* return the pointer to the left or right side of p, or p itself,
419: depending on the optype of p */
420:
421: switch( c ) {
422:
423: case '1':
424: case '2':
425: case '3':
426: return( &resc[c-'1'] );
427:
428: case 'L':
429: return( optype( p->in.op ) == LTYPE ? p : p->in.left );
430:
431: case 'R':
432: return( optype( p->in.op ) != BITYPE ? p : p->in.right );
433:
434: }
435: cerror( "bad getlr: %c", c );
436: /* NOTREACHED */
437: }
438: # ifdef MULTILEVEL
439:
440: union mltemplate{
441: struct ml_head{
442: int tag; /* identifies class of tree */
443: int subtag; /* subclass of tree */
444: union mltemplate * nexthead; /* linked by mlinit() */
445: } mlhead;
446: struct ml_node{
447: int op; /* either an operator or op description */
448: int nshape; /* shape of node */
449: /* both op and nshape must match the node.
450: * where the work is to be done entirely by
451: * op, nshape can be SANY, visa versa, op can
452: * be OPANY.
453: */
454: int ntype; /* type descriptor from mfile2 */
455: } mlnode;
456: };
457:
458: # define MLSZ 30
459:
460: extern union mltemplate mltree[];
461: int mlstack[MLSZ];
462: int *mlsp; /* pointing into mlstack */
463: NODE * ststack[MLSZ];
464: NODE **stp; /* pointing into ststack */
465:
466: mlinit(){
467: union mltemplate **lastlink;
468: register int union mltemplate *n;
469: register int mlop;
470:
471: lastlink = &(mltree[0].nexthead);
472: n = &mltree[0];
473: for( ; (n++)->mlhead.tag != 0;
474: *lastlink = ++n, lastlink = &(n->mlhead.nexthead) ){
475: # ifndef BUG3
476: if( vdebug )printf("mlinit: %d\n",(n-1)->mlhead.tag);
477: # endif
478: /* wander thru a tree with a stack finding
479: * its structure so the next header can be located.
480: */
481: mlsp = mlstack;
482:
483: for( ;; ++n ){
484: if( (mlop = n->mlnode.op) < OPSIMP ){
485: switch( optype(mlop) ){
486:
487: default:
488: cerror("(1)unknown opcode: %o",mlop);
489: case BITYPE:
490: goto binary;
491: case UTYPE:
492: break;
493: case LTYPE:
494: goto leaf;
495: }
496: }
497: else{
498: if( mamask[mlop-OPSIMP] &
499: (SIMPFLG|COMMFLG|MULFLG|DIVFLG|LOGFLG|FLOFLG|SHFFLG) ){
500: binary:
501: *mlsp++ = BITYPE;
502: }
503: else if( ! (mamask[mlop-OPSIMP] & UTYPE) ){/* includes OPANY */
504:
505: leaf:
506: if( mlsp == mlstack )
507: goto tree_end;
508: else if ( *--mlsp != BITYPE )
509: cerror("(1)bad multi-level tree descriptor around mltree[%d]",
510: n-mltree);
511: }
512: }
513: }
514: tree_end: /* n points to final leaf */
515: ;
516: }
517: # ifndef BUG3
518: if( vdebug > 3 ){
519: printf("mltree={\n");
520: for( n= &(mltree[0]); n->mlhead.tag != 0; ++n)
521: printf("%o: %d, %d, %o,\n",n,
522: n->mlhead.tag,n->mlhead.subtag,n->mlhead.nexthead);
523: printf(" }\n");
524: }
525: # endif
526: }
527:
528: mlmatch( subtree, target, subtarget ) NODE * subtree; int target,subtarget;{
529: /*
530: * does subtree match a multi-level tree with
531: * tag "target"? Return zero on failure,
532: * non-zero subtag on success (or MDONE if
533: * there is a zero subtag field).
534: */
535: union mltemplate *head; /* current template header */
536: register union mltemplate *n; /* node being matched */
537: NODE * st; /* subtree being matched */
538: register int mlop;
539:
540: # ifndef BUG3
541: if( vdebug ) printf("mlmatch(%o,%d)\n",subtree,target);
542: # endif
543: for( head = &(mltree[0]); head->mlhead.tag != 0;
544: head=head->mlhead.nexthead){
545: # ifndef BUG3
546: if( vdebug > 1 )printf("mlmatch head(%o) tag(%d)\n",
547: head->mlhead.tag);
548: # endif
549: if( head->mlhead.tag != target )continue;
550: if( subtarget && head->mlhead.subtag != subtarget)continue;
551: # ifndef BUG3
552: if( vdebug ) printf("mlmatch for %d\n",target);
553: # endif
554:
555: /* potential for match */
556:
557: n = head + 1;
558: st = subtree;
559: stp = ststack;
560: mlsp = mlstack;
561: /* compare n->op, ->nshape, ->ntype to
562: * the subtree node st
563: */
564: for( ;; ++n ){ /* for each node in multi-level template */
565: /* opmatch */
566: if( n->op < OPSIMP ){
567: if( st->op != n->op )break;
568: }
569: else {
570: register int opmtemp;
571: if((opmtemp=mamask[n->op-OPSIMP])&SPFLG){
572: if(st->op!=NAME && st->op!=ICON && st->op!=OREG &&
573: ! shltype(st->op,st)) break;
574: }
575: else if((dope[st->op]&(opmtemp|ASGFLG))!=opmtemp) break;
576: }
577: /* check shape and type */
578:
579: if( ! tshape( st, n->mlnode.nshape ) ) break;
580: if( ! ttype( st->type, n->mlnode.ntype ) ) break;
581:
582: /* that node matched, let's try another */
583: /* must advance both st and n and halt at right time */
584:
585: if( (mlop = n->mlnode.op) < OPSIMP ){
586: switch( optype(mlop) ){
587:
588: default:
589: cerror("(2)unknown opcode: %o",mlop);
590: case BITYPE:
591: goto binary;
592: case UTYPE:
593: st = st->left;
594: break;
595: case LTYPE:
596: goto leaf;
597: }
598: }
599: else{
600: if( mamask[mlop - OPSIMP] &
601: (SIMPFLG|COMMFLG|MULFLG|DIVFLG|LOGFLG|FLOFLG|SHFFLG) ){
602: binary:
603: *mlsp++ = BITYPE;
604: *stp++ = st;
605: st = st->left;
606: }
607: else if( ! (mamask[mlop-OPSIMP] & UTYPE) ){/* includes OPANY */
608:
609: leaf:
610: if( mlsp == mlstack )
611: goto matched;
612: else if ( *--mlsp != BITYPE )
613: cerror("(2)bad multi-level tree descriptor around mltree[%d]",
614: n-mltree);
615: st = (*--stp)->right;
616: }
617: else /* UNARY */ st = st->left;
618: }
619: continue;
620:
621: matched:
622: /* complete multi-level match successful */
623: # ifndef BUG3
624: if( vdebug ) printf("mlmatch() success\n");
625: # endif
626: if( head->mlhead.subtag == 0 ) return( MDONE );
627: else {
628: # ifndef BUG3
629: if( vdebug )printf("\treturns %d\n",
630: head->mlhead.subtag );
631: # endif
632: return( head->mlhead.subtag );
633: }
634: }
635: }
636: return( 0 );
637: }
638: # endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.