|
|
1.1 root 1: # include "mfile2"
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 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: case LONG:
196: return( tword & TLONG );
197: case FLOAT:
198: return( tword & TFLOAT );
199: case DOUBLE:
200: return( tword & TDOUBLE );
201: }
202:
203: return(0);
204: }
205:
206: struct optab *rwtable;
207:
208: struct optab *opptr[DSIZE];
209:
210: setrew(){
211: /* set rwtable to first value which allows rewrite */
212: register struct optab *q;
213: register int i;
214:
215: # ifdef MULTILEVEL
216: /* also initialize multi-level tree links */
217: mlinit();
218: # endif
219:
220: for( q = table; q->op != FREE; ++q ){
221: if( q->needs == REWRITE ){
222: rwtable = q;
223: goto more;
224: }
225: }
226: cerror( "bad setrew" );
227:
228:
229: more:
230: for( i=0; i<DSIZE; ++i ){
231: if( dope[i] ){ /* there is an op... */
232: for( q=table; q->op != FREE; ++q ){
233: /* beware; things like LTYPE that match
234: multiple things in the tree must
235: not try to look at the NIL at this
236: stage of things! Put something else
237: first in table.c */
238: /* at one point, the operator matching was 15% of the
239: total comile time; thus, the function
240: call that was here was removed...
241: */
242:
243: if( q->op < OPSIMP ){
244: if( q->op==i ) break;
245: }
246: else {
247: register opmtemp;
248: if((opmtemp=mamask[q->op - OPSIMP])&SPFLG){
249: if( i==NAME || i==ICON || i==OREG ) break;
250: else if( shltype( i, NIL ) ) break;
251: }
252: else if( (dope[i]&(opmtemp|ASGFLG)) == opmtemp ) break;
253: }
254: }
255: opptr[i] = q;
256: }
257: }
258: }
259:
260: match( p, cookie ) NODE *p; {
261: /* called by: order, gencall
262: look for match in table and generate code if found unless
263: entry specified REWRITE.
264: returns MDONE, MNOPE, or rewrite specification from table */
265:
266: register struct optab *q;
267: register NODE *r;
268:
269: rcount();
270: if( cookie == FORREW ) q = rwtable;
271: else q = opptr[p->in.op];
272:
273: for( ; q->op != FREE; ++q ){
274:
275: /* at one point the call that was here was over 15% of the total time;
276: thus the function call was expanded inline */
277: if( q->op < OPSIMP ){
278: if( q->op!=p->in.op ) continue;
279: }
280: else {
281: register opmtemp;
282: if((opmtemp=mamask[q->op - OPSIMP])&SPFLG){
283: if( p->in.op!=NAME && p->in.op!=ICON && p->in.op!= OREG &&
284: ! shltype( p->in.op, p ) ) continue;
285: }
286: else if( (dope[p->in.op]&(opmtemp|ASGFLG)) != opmtemp ) continue;
287: }
288:
289: if( !(q->visit & cookie ) ) continue;
290: r = getlr( p, 'L' ); /* see if left child matches */
291: if( !tshape( r, q->lshape ) ) continue;
292: if( !ttype( r->in.type, q->ltype ) ) continue;
293: r = getlr( p, 'R' ); /* see if right child matches */
294: if( !tshape( r, q->rshape ) ) continue;
295: if( !ttype( r->in.type, q->rtype ) ) continue;
296:
297: /* REWRITE means no code from this match but go ahead
298: and rewrite node to help future match */
299: if( q->needs & REWRITE ) return( q->rewrite );
300: if( !allo( p, q ) ) continue; /* if can't generate code, skip entry */
301:
302: /* resources are available */
303:
304: expand( p, cookie, q->cstring ); /* generate code */
305: reclaim( p, q->rewrite, cookie );
306:
307: return(MDONE);
308:
309: }
310:
311: return(MNOPE);
312: }
313:
314: int rtyflg = 0;
315:
316: expand( p, cookie, cp ) NODE *p; register char *cp; {
317: /* generate code by interpreting table entry */
318:
319: register char c;
320: CONSZ val;
321:
322: rtyflg = 0;
323:
324: for( ; *cp; ++cp ){
325: switch( *cp ){
326:
327: default:
328: PUTCHAR( *cp );
329: continue; /* this is the usual case... */
330:
331: case 'T':
332: /* rewrite register type is suppressed */
333: rtyflg = 1;
334: continue;
335:
336: case 'Z': /* special machine dependent operations */
337: # ifdef NEWZZZ
338: switch( c = *++cp ) {
339:
340: case '1':
341: case '2':
342: case '3':
343: case 'R':
344: case 'L': /* get down first */
345: zzzcode( getlr( p, c ), *++cp );
346: break;
347: default: /* normal zzzcode processing otherwise */
348: zzzcode( p, c );
349: break;
350: }
351: # else
352: zzzcode( p, *++cp );
353: # endif
354: continue;
355:
356: case 'F': /* this line deleted if FOREFF is active */
357: if( cookie & FOREFF ) while( *++cp != '\n' ) ; /* VOID */
358: continue;
359:
360: case 'S': /* field size */
361: printf( "%d", fldsz );
362: continue;
363:
364: case 'H': /* field shift */
365: printf( "%d", fldshf );
366: continue;
367:
368: case 'M': /* field mask */
369: case 'N': /* complement of field mask */
370: val = 1;
371: val <<= fldsz;
372: --val;
373: val <<= fldshf;
374: adrcon( *cp=='M' ? val : ~val );
375: continue;
376:
377: case 'L': /* output special label field */
378: printf( "%d", p->bn.label );
379: continue;
380:
381: case 'O': /* opcode string */
382: hopcode( *++cp, p->in.op );
383: continue;
384:
385: case 'B': /* byte offset in word */
386: val = getlr(p,*++cp)->tn.lval;
387: val = BYTEOFF(val);
388: printf( CONFMT, val );
389: continue;
390:
391: case 'C': /* for constant value only */
392: conput( getlr( p, *++cp ) );
393: continue;
394:
395: case 'I': /* in instruction */
396: insput( getlr( p, *++cp ) );
397: continue;
398:
399: case 'A': /* address of */
400: adrput( getlr( p, *++cp ) );
401: continue;
402:
403: case 'U': /* for upper half of address, only */
404: upput( getlr( p, *++cp ) );
405: continue;
406:
407: }
408:
409: }
410:
411: }
412:
413: NODE *
414: getlr( p, c ) NODE *p; {
415:
416: /* return the pointer to the left or right side of p, or p itself,
417: depending on the optype of p */
418:
419: switch( c ) {
420:
421: case '1':
422: case '2':
423: case '3':
424: return( &resc[c-'1'] );
425:
426: case 'L':
427: return( optype( p->in.op ) == LTYPE ? p : p->in.left );
428:
429: case 'R':
430: return( optype( p->in.op ) != BITYPE ? p : p->in.right );
431:
432: }
433: cerror( "bad getlr: %c", c );
434: /* NOTREACHED */
435: }
436: # ifdef MULTILEVEL
437:
438: union mltemplate{
439: struct ml_head{
440: int tag; /* identifies class of tree */
441: int subtag; /* subclass of tree */
442: union mltemplate * nexthead; /* linked by mlinit() */
443: } mlhead;
444: struct ml_node{
445: int op; /* either an operator or op description */
446: int nshape; /* shape of node */
447: /* both op and nshape must match the node.
448: * where the work is to be done entirely by
449: * op, nshape can be SANY, visa versa, op can
450: * be OPANY.
451: */
452: int ntype; /* type descriptor from mfile2 */
453: } mlnode;
454: };
455:
456: # define MLSZ 30
457:
458: extern union mltemplate mltree[];
459: int mlstack[MLSZ];
460: int *mlsp; /* pointing into mlstack */
461: NODE * ststack[MLSZ];
462: NODE **stp; /* pointing into ststack */
463:
464: mlinit(){
465: union mltemplate **lastlink;
466: register union mltemplate *n;
467: register mlop;
468:
469: lastlink = &(mltree[0].nexthead);
470: n = &mltree[0];
471: for( ; (n++)->mlhead.tag != 0;
472: *lastlink = ++n, lastlink = &(n->mlhead.nexthead) ){
473: # ifndef BUG3
474: if( vdebug )printf("mlinit: %d\n",(n-1)->mlhead.tag);
475: # endif
476: /* wander thru a tree with a stack finding
477: * its structure so the next header can be located.
478: */
479: mlsp = mlstack;
480:
481: for( ;; ++n ){
482: if( (mlop = n->mlnode.op) < OPSIMP ){
483: switch( optype(mlop) ){
484:
485: default:
486: cerror("(1)unknown opcode: %o",mlop);
487: case BITYPE:
488: goto binary;
489: case UTYPE:
490: break;
491: case LTYPE:
492: goto leaf;
493: }
494: }
495: else{
496: if( mamask[mlop-OPSIMP] &
497: (SIMPFLG|COMMFLG|MULFLG|DIVFLG|LOGFLG|FLOFLG|SHFFLG) ){
498: binary:
499: *mlsp++ = BITYPE;
500: }
501: else if( ! (mamask[mlop-OPSIMP] & UTYPE) ){/* includes OPANY */
502:
503: leaf:
504: if( mlsp == mlstack )
505: goto tree_end;
506: else if ( *--mlsp != BITYPE )
507: cerror("(1)bad multi-level tree descriptor around mltree[%d]",
508: n-mltree);
509: }
510: }
511: }
512: tree_end: /* n points to final leaf */
513: ;
514: }
515: # ifndef BUG3
516: if( vdebug > 3 ){
517: printf("mltree={\n");
518: for( n= &(mltree[0]); n->mlhead.tag != 0; ++n)
519: printf("%o: %d, %d, %o,\n",n,
520: n->mlhead.tag,n->mlhead.subtag,n->mlhead.nexthead);
521: printf(" }\n");
522: }
523: # endif
524: }
525:
526: mlmatch( subtree, target, subtarget ) NODE * subtree; int target,subtarget;{
527: /*
528: * does subtree match a multi-level tree with
529: * tag "target"? Return zero on failure,
530: * non-zero subtag on success (or MDONE if
531: * there is a zero subtag field).
532: */
533: union mltemplate *head; /* current template header */
534: register union mltemplate *n; /* node being matched */
535: NODE * st; /* subtree being matched */
536: register int mlop;
537:
538: # ifndef BUG3
539: if( vdebug ) printf("mlmatch(%o,%d)\n",subtree,target);
540: # endif
541: for( head = &(mltree[0]); head->mlhead.tag != 0;
542: head=head->mlhead.nexthead){
543: # ifndef BUG3
544: if( vdebug > 1 )printf("mlmatch head(%o) tag(%d)\n",
545: head->mlhead.tag);
546: # endif
547: if( head->mlhead.tag != target )continue;
548: if( subtarget && head->mlhead.subtag != subtarget)continue;
549: # ifndef BUG3
550: if( vdebug ) printf("mlmatch for %d\n",target);
551: # endif
552:
553: /* potential for match */
554:
555: n = head + 1;
556: st = subtree;
557: stp = ststack;
558: mlsp = mlstack;
559: /* compare n->op, ->nshape, ->ntype to
560: * the subtree node st
561: */
562: for( ;; ++n ){ /* for each node in multi-level template */
563: /* opmatch */
564: if( n->op < OPSIMP ){
565: if( st->op != n->op )break;
566: }
567: else {
568: register opmtemp;
569: if((opmtemp=mamask[n->op-OPSIMP])&SPFLG){
570: if(st->op!=NAME && st->op!=ICON && st->op!=OREG &&
571: ! shltype(st->op,st)) break;
572: }
573: else if((dope[st->op]&(opmtemp|ASGFLG))!=opmtemp) break;
574: }
575: /* check shape and type */
576:
577: if( ! tshape( st, n->mlnode.nshape ) ) break;
578: if( ! ttype( st->type, n->mlnode.ntype ) ) break;
579:
580: /* that node matched, let's try another */
581: /* must advance both st and n and halt at right time */
582:
583: if( (mlop = n->mlnode.op) < OPSIMP ){
584: switch( optype(mlop) ){
585:
586: default:
587: cerror("(2)unknown opcode: %o",mlop);
588: case BITYPE:
589: goto binary;
590: case UTYPE:
591: st = st->left;
592: break;
593: case LTYPE:
594: goto leaf;
595: }
596: }
597: else{
598: if( mamask[mlop - OPSIMP] &
599: (SIMPFLG|COMMFLG|MULFLG|DIVFLG|LOGFLG|FLOFLG|SHFFLG) ){
600: binary:
601: *mlsp++ = BITYPE;
602: *stp++ = st;
603: st = st->left;
604: }
605: else if( ! (mamask[mlop-OPSIMP] & UTYPE) ){/* includes OPANY */
606:
607: leaf:
608: if( mlsp == mlstack )
609: goto matched;
610: else if ( *--mlsp != BITYPE )
611: cerror("(2)bad multi-level tree descriptor around mltree[%d]",
612: n-mltree);
613: st = (*--stp)->right;
614: }
615: else /* UNARY */ st = st->left;
616: }
617: continue;
618:
619: matched:
620: /* complete multi-level match successful */
621: # ifndef BUG3
622: if( vdebug ) printf("mlmatch() success\n");
623: # endif
624: if( head->mlhead.subtag == 0 ) return( MDONE );
625: else {
626: # ifndef BUG3
627: if( vdebug )printf("\treturns %d\n",
628: head->mlhead.subtag );
629: # endif
630: return( head->mlhead.subtag );
631: }
632: }
633: }
634: return( 0 );
635: }
636: # endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.