home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V7 / usr / src / cmd / mip / match.c < prev    next >
Encoding:
C/C++ Source or Header  |  1979-01-14  |  7.9 KB  |  378 lines

  1. # include "mfile2"
  2.  
  3.  
  4. int fldsz, fldshf;
  5.  
  6. static int mamask[] = { /* masks for matching dope with shapes */
  7.     SIMPFLG,        /* OPSIMP */
  8.     SIMPFLG|ASGFLG,        /* ASG OPSIMP */
  9.     COMMFLG,    /* OPCOMM */
  10.     COMMFLG|ASGFLG,    /* ASG OPCOMM */
  11.     MULFLG,        /* OPMUL */
  12.     MULFLG|ASGFLG,    /* ASG OPMUL */
  13.     DIVFLG,        /* OPDIV */
  14.     DIVFLG|ASGFLG,    /* ASG OPDIV */
  15.     UTYPE,        /* OPUNARY */
  16.     TYFLG,        /* ASG OPUNARY is senseless */
  17.     LTYPE,        /* OPLEAF */
  18.     TYFLG,        /* ASG OPLEAF is senseless */
  19.     0,        /* OPANY */
  20.     ASGOPFLG|ASGFLG,    /* ASG OPANY */
  21.     LOGFLG,        /* OPLOG */
  22.     TYFLG,        /* ASG OPLOG is senseless */
  23.     FLOFLG,        /* OPFLOAT */
  24.     FLOFLG|ASGFLG,    /* ASG OPFLOAT */
  25.     SHFFLG,        /* OPSHFT */
  26.     SHFFLG|ASGFLG,    /* ASG OPSHIFT */
  27.     SPFLG,        /* OPLTYPE */
  28.     TYFLG,        /* ASG OPLTYPE is senseless */
  29.     };
  30.  
  31. int sdebug = 0;
  32.  
  33. tshape( p, shape ) NODE *p; {
  34.     /* return true if shape is appropriate for the node p
  35.        side effect for SFLD is to set up fldsz,etc */
  36.     register o, mask;
  37.  
  38.     o = p->op;
  39.  
  40.     if( sdebug ){
  41.         printf( "tshape( %o, %o), op = %d\n", p, shape, o );
  42.         }
  43.  
  44.     if( shape & SPECIAL ){
  45.  
  46.         switch( shape ){
  47.  
  48.         case SZERO:
  49.         case SONE:
  50.         case SMONE:
  51.             if( o != ICON || p->name[0] ) return(0);
  52.             if( p->lval == 0 && shape == SZERO ) return(1);
  53.             else if( p->lval == 1 && shape == SONE ) return(1);
  54.             else if( p->lval == -1 && shape == SMONE ) return(1);
  55.             else return(0);
  56.  
  57.         default:
  58.             return( special( p, shape ) );
  59.             }
  60.         }
  61.  
  62.     if( shape & SANY ) return(1);
  63.  
  64.     if( (shape&INTEMP) && shtemp(p) ) return(1);
  65.  
  66.     if( (shape&SWADD) && (o==NAME||o==OREG) ){
  67.         if( BYTEOFF(p->lval) ) return(0);
  68.         }
  69.  
  70.     switch( o ){
  71.  
  72.     case NAME:
  73.         return( shape&SNAME );
  74.     case ICON:
  75.         mask = SCON;
  76.         return( shape & mask );
  77.  
  78.     case FLD:
  79.         if( shape & SFLD ){
  80.             if( !flshape( p->left ) ) return(0);
  81.             /* it is a FIELD shape; make side-effects */
  82.             o = p->rval;
  83.             fldsz = UPKFSZ(o);
  84. # ifdef RTOLBYTES
  85.             fldshf = UPKFOFF(o);
  86. # else
  87.             fldshf = SZINT - fldsz - UPKFOFF(o);
  88. # endif
  89.             return(1);
  90.             }
  91.         return(0);
  92.  
  93.     case CCODES:
  94.         return( shape&SCC );
  95.  
  96.     case REG:
  97.         /* distinctions:
  98.         SAREG    any scalar register
  99.         STAREG    any temporary scalar register
  100.         SBREG    any lvalue (index) register
  101.         STBREG    any temporary lvalue register
  102.         */
  103.         mask = isbreg( p->rval ) ? SBREG : SAREG;
  104.         if( istreg( p->rval ) && busy[p->rval]<=1 ) mask |= mask==SAREG ? STAREG : STBREG;
  105.         return( shape & mask );
  106.  
  107.     case OREG:
  108.         return( shape & SOREG );
  109.  
  110.     case UNARY MUL:
  111.         /* return STARNM or STARREG or 0 */
  112.         return( shumul(p->left) & shape );
  113.  
  114.         }
  115.  
  116.     return(0);
  117.     }
  118.  
  119. int tdebug = 0;
  120.  
  121. ttype( t, tword ) TWORD t; {
  122.     /* does the type t match tword */
  123.  
  124.     if( tword & TANY ) return(1);
  125.  
  126.     if( tdebug ){
  127.         printf( "ttype( %o, %o )\n", t, tword );
  128.         }
  129.     if( ISPTR(t) && (tword&TPTRTO) ) {
  130.         do {
  131.             t = DECREF(t);
  132.         } while ( ISARY(t) );
  133.             /* arrays that are left are usually only
  134.                in structure references... */
  135.         return( ttype( t, tword&(~TPTRTO) ) );
  136.         }
  137.     if( t != BTYPE(t) ) return( tword & TPOINT ); /* TPOINT means not simple! */
  138.     if( tword & TPTRTO ) return(0);
  139.  
  140.     switch( t ){
  141.  
  142.     case CHAR:
  143.         return( tword & TCHAR );
  144.     case SHORT:
  145.         return( tword & TSHORT );
  146.     case STRTY:
  147.     case UNIONTY:
  148.         return( tword & TSTRUCT );
  149.     case INT:
  150.         return( tword & TINT );
  151.     case UNSIGNED:
  152.         return( tword & TUNSIGNED );
  153.     case USHORT:
  154.         return( tword & TUSHORT );
  155.     case UCHAR:
  156.         return( tword & TUCHAR );
  157.     case ULONG:
  158.         return( tword & TULONG );
  159.     case LONG:
  160.         return( tword & TLONG );
  161.     case FLOAT:
  162.         return( tword & TFLOAT );
  163.     case DOUBLE:
  164.         return( tword & TDOUBLE );
  165.         }
  166.  
  167.     return(0);
  168.     }
  169.  
  170. struct optab *rwtable;
  171.  
  172. struct optab *opptr[DSIZE];
  173.  
  174. setrew(){
  175.     /* set rwtable to first value which allows rewrite */
  176.     register struct optab *q;
  177.     register int i;
  178.  
  179.     for( q = table; q->op != FREE; ++q ){
  180.         if( q->needs == REWRITE ){
  181.             rwtable = q;
  182.             goto more;
  183.             }
  184.         }
  185.     cerror( "bad setrew" );
  186.  
  187.  
  188.     more:
  189.     for( i=0; i<DSIZE; ++i ){
  190.         if( dope[i] ){ /* there is an op... */
  191.             for( q=table; q->op != FREE; ++q ){
  192.                 /*  beware; things like LTYPE that match
  193.                     multiple things in the tree must
  194.                     not try to look at the NIL at this
  195.                     stage of things!  Put something else
  196.                     first in table.c  */
  197.                 /* at one point, the operator matching was 15% of the
  198.                     total comile time; thus, the function
  199.                     call that was here was removed...
  200.                 */
  201.  
  202.                 if( q->op < OPSIMP ){
  203.                     if( q->op==i ) break;
  204.                     }
  205.                 else {
  206.                     register opmtemp;
  207.                     if((opmtemp=mamask[q->op - OPSIMP])&SPFLG){
  208.                         if( i==NAME || i==ICON || i==OREG ) break;
  209.                         else if( shltype( i, NIL ) ) break;
  210.                         }
  211.                     else if( (dope[i]&(opmtemp|ASGFLG)) == opmtemp ) break;
  212.                     }
  213.                 }
  214.             opptr[i] = q;
  215.             }
  216.         }
  217.     }
  218.  
  219. match( p, cookie ) NODE *p; {
  220.     /* called by: order, gencall
  221.        look for match in table and generate code if found unless
  222.        entry specified REWRITE.
  223.        returns MDONE, MNOPE, or rewrite specification from table */
  224.  
  225.     register struct optab *q;
  226.     register NODE *r;
  227.  
  228.     rcount();
  229.     if( cookie == FORREW ) q = rwtable;
  230.     else q = opptr[p->op];
  231.  
  232.     for( ; q->op != FREE; ++q ){
  233.  
  234.         /* at one point the call that was here was over 15% of the total time;
  235.             thus the function call was expanded inline */
  236.         if( q->op < OPSIMP ){
  237.             if( q->op!=p->op ) continue;
  238.             }
  239.         else {
  240.             register opmtemp;
  241.             if((opmtemp=mamask[q->op - OPSIMP])&SPFLG){
  242.                 if( p->op!=NAME && p->op!=ICON && p->op!= OREG &&
  243.                     ! shltype( p->op, p ) ) continue;
  244.                 }
  245.             else if( (dope[p->op]&(opmtemp|ASGFLG)) != opmtemp ) continue;
  246.             }
  247.  
  248.         if( !(q->visit & cookie ) ) continue;
  249.         r = getlr( p, 'L' );            /* see if left child matches */
  250.         if( !tshape( r, q->lshape ) ) continue;
  251.         if( !ttype( r->type, q->ltype ) ) continue;
  252.         r = getlr( p, 'R' );            /* see if right child matches */
  253.         if( !tshape( r, q->rshape ) ) continue;
  254.         if( !ttype( r->type, q->rtype ) ) continue;
  255.  
  256.             /* REWRITE means no code from this match but go ahead
  257.                and rewrite node to help future match */
  258.         if( q->needs & REWRITE ) return( q->rewrite );
  259.         if( !allo( p, q ) ) continue;            /* if can't generate code, skip entry */
  260.  
  261.         /* resources are available */
  262.  
  263.         expand( p, cookie, q->cstring );        /* generate code */
  264.         reclaim( p, q->rewrite, cookie );
  265.  
  266.         return(MDONE);
  267.  
  268.         }
  269.  
  270.     return(MNOPE);
  271.     }
  272.  
  273. int rtyflg = 0;
  274.  
  275. expand( p, cookie, cp ) NODE *p;  register char *cp; {
  276.     /* generate code by interpreting table entry */
  277.  
  278.     CONSZ val;
  279.  
  280.     rtyflg = 0;
  281.  
  282.     for( ; *cp; ++cp ){
  283.         switch( *cp ){
  284.  
  285.         default:
  286.             PUTCHAR( *cp );
  287.             continue;  /* this is the usual case... */
  288.  
  289.         case 'T':
  290.             /* rewrite register type is suppressed */
  291.             rtyflg = 1;
  292.             continue;
  293.  
  294.         case 'Z':  /* special machine dependent operations */
  295.             zzzcode( p, *++cp );
  296.             continue;
  297.  
  298.         case 'F':  /* this line deleted if FOREFF is active */
  299.             if( cookie & FOREFF ) while( *++cp != '\n' ) ; /* VOID */
  300.             continue;
  301.  
  302.         case 'S':  /* field size */
  303.             printf( "%d", fldsz );
  304.             continue;
  305.  
  306.         case 'H':  /* field shift */
  307.             printf( "%d", fldshf );
  308.             continue;
  309.  
  310.         case 'M':  /* field mask */
  311.         case 'N':  /* complement of field mask */
  312.             val = 1;
  313.             val <<= fldsz;
  314.             --val;
  315.             val <<= fldshf;
  316.             adrcon( *cp=='M' ? val : ~val );
  317.             continue;
  318.  
  319.         case 'L':  /* output special label field */
  320.             printf( "%d", p->label );
  321.             continue;
  322.  
  323.         case 'O':  /* opcode string */
  324.             hopcode( *++cp, p->op );
  325.             continue;
  326.  
  327.         case 'B':  /* byte offset in word */
  328.             val = getlr(p,*++cp)->lval;
  329.             val = BYTEOFF(val);
  330.             printf( CONFMT, val );
  331.             continue;
  332.  
  333.         case 'C': /* for constant value only */
  334.             conput( getlr( p, *++cp ) );
  335.             continue;
  336.  
  337.         case 'I': /* in instruction */
  338.             insput( getlr( p, *++cp ) );
  339.             continue;
  340.  
  341.         case 'A': /* address of */
  342.             adrput( getlr( p, *++cp ) );
  343.             continue;
  344.  
  345.         case 'U': /* for upper half of address, only */
  346.             upput( getlr( p, *++cp ) );
  347.             continue;
  348.  
  349.             }
  350.  
  351.         }
  352.  
  353.     }
  354.  
  355. NODE *
  356. getlr( p, c ) NODE *p; {
  357.  
  358.     /* return the pointer to the left or right side of p, or p itself,
  359.        depending on the optype of p */
  360.  
  361.     switch( c ) {
  362.  
  363.     case '1':
  364.     case '2':
  365.     case '3':
  366.         return( &resc[c-'1'] );
  367.  
  368.     case 'L':
  369.         return( optype( p->op ) == LTYPE ? p : p->left );
  370.  
  371.     case 'R':
  372.         return( optype( p->op ) != BITYPE ? p : p->right );
  373.  
  374.         }
  375.     cerror( "bad getlr: %c", c );
  376.     /* NOTREACHED */
  377.     }
  378.