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

Defined functions

expand defined in line 322; used 1 times
getlr defined in line 421; used 12 times
match defined in line 266; used 2 times
mlinit defined in line 472; used 1 times
mlmatch defined in line 534; used 1 times
  • in line 83
setrew defined in line 216; used 1 times
tshape defined in line 44; used 6 times
ttype defined in line 160; used 4 times

Defined variables

fldshf defined in line 15; used 4 times
fldsz defined in line 15; used 4 times
mamask defined in line 17; used 7 times
mlsp defined in line 468; used 8 times
mlstack defined in line 467; used 4 times
opptr defined in line 214; used 2 times
rtyflg defined in line 320; used 2 times
rwtable defined in line 212; used 2 times
sccsid defined in line 2; never used
sdebug defined in line 42; used 2 times
stp defined in line 470; used 3 times
ststack defined in line 469; used 1 times
tdebug defined in line 158; never used

Defined struct's

ml_head defined in line 447; never used
ml_node defined in line 452; never used

Defined union's

mltemplate defined in line 446; used 12 times

Defined macros

MLSZ defined in line 464; used 2 times
NOINDIRECT defined in line 9; used 1 times
Last modified: 1985-08-25
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1780
Valid CSS Valid XHTML 1.0 Strict