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