# 2.11BSD#431 - /usr/src/lib/mip/allo.c

##### Functions

    allchk            X
    allo              X
    allo0             X
    freereg           X
    freetemp          X
    ncopy             X
    rbusy             X
    recl2             X
    reclaim           X
    rfree             X
    rwprint           X
    shareit           X
    tcopy             X
    usable            X
    ushare            X

##### Variables

    busy              X
    maxa              X
    maxb              X
    mina              X
    minb              X
    rdebug            X
    resc              X

       1: #if !defined(lint) && defined(DOSCCS)
       2: static char *sccsid ="@(#)allo.c	4.8.1 (2.11BSD GTE) 1/17/95";
       3: #endif lint
       4:
       5: # include "pass2.h"
       6:
       7: NODE resc[3];
       8:
       9: int busy[REGSZ];
      10:
      11: int maxa, mina, maxb, minb;
      12:
      13: # ifndef ALLO0
      14: allo0(){ /* free everything */
      15:
      16:     register i;
      17:
      18:     maxa = maxb = -1;
      19:     mina = minb = 0;
      20:
      21:     REGLOOP(i){
      22:         busy[i] = 0;
      23:         if( rstatus[i] & STAREG ){
      24:             if( maxa<0 ) mina = i;
      25:             maxa = i;
      26:             }
      27:         if( rstatus[i] & STBREG ){
      28:             if( maxb<0 ) minb = i;
      29:             maxb = i;
      30:             }
      31:         }
      32:     }
      33: # endif
      34:
      35: # ifndef ALLO
      36: allo( p, q ) NODE *p; struct optab *q; {
      37:     OFFSZ freetemp();
      38:     register n, i, j;
      39:     int either;
      40:
      41:     n = q->needs;
      42:     either = ( EITHER & n );
      43:     i = 0;
      44:
      45:     while( n & NACOUNT ){
      46:         resc[i].in.op = REG;
      47:         resc[i].tn.rval = freereg( p, n&NAMASK );
      48:         resc[i].tn.lval = 0;
      49: #ifdef FLEXNAMES
      50:         resc[i].in.name = "";
      51: #else
      52:         resc[i].in.name[0] = '\0';
      53: #endif
      54:         n -= NAREG;
      55:         ++i;
      56:         }
      57:
      58:     if (either) { /* all or nothing at all */
      59:         for( j = 0; j < i; j++ )
      60:             if( resc[j].tn.rval < 0 ) { /* nothing */
      61:                 i = 0;
      62:                 break;
      63:                 }
      64:         if( i != 0 ) goto ok; /* all */
      65:         }
      66:
      67:     while( n & NBCOUNT ){
      68:         resc[i].in.op = REG;
      69:         resc[i].tn.rval = freereg( p, n&NBMASK );
      70:         resc[i].tn.lval = 0;
      71: #ifdef FLEXNAMES
      72:         resc[i].in.name = "";
      73: #else
      74:         resc[i].in.name[0] = '\0';
      75: #endif
      76:         n -= NBREG;
      77:         ++i;
      78:         }
      79:     if (either) { /* all or nothing at all */
      80:         for( j = 0; j < i; j++ )
      81:             if( resc[j].tn.rval < 0 ) { /* nothing */
      82:                 i = 0;
      83:                 break;
      84:                 }
      85:         if( i != 0 ) goto ok; /* all */
      86:         }
      87:
      88:     if( n & NTMASK ){
      89:         resc[i].in.op = OREG;
      90:         resc[i].tn.rval = TMPREG;
      91:         if( p->in.op == STCALL || p->in.op == STARG || p->in.op == UNARY STCALL || p->in.op == STASG ){
      92:             resc[i].tn.lval = freetemp( (SZCHAR*p->stn.stsize + (SZINT-1))/SZINT );
      93:             }
      94:         else {
      95:             resc[i].tn.lval = freetemp( (n&NTMASK)/NTEMP );
      96:             }
      97: #ifdef FLEXNAMES
      98:         resc[i].in.name = "";
      99: #else
     100:         resc[i].in.name[0] = '\0';
     101: #endif
     102:
     103:         resc[i].tn.lval = BITOOR(resc[i].tn.lval);
     104:         ++i;
     105:         }
     106:
     107:     /* turn off "temporarily busy" bit */
     108:
     109:     ok:
     110:     REGLOOP(j){
     111:         busy[j] &= ~TBUSY;
     112:         }
     113:
     114:     for( j=0; j<i; ++j ) if( resc[j].tn.rval < 0 ) return(0);
     115:     return(1);
     116:
     117:     }
     118: # endif
     119:
     120: extern OFFSZ offsz;
     121:
     122: OFFSZ
     123: freetemp( k ){ /* allocate k integers worth of temp space */
     124:     /* we also make the convention that, if the number of words is more than 1,
     125: 	/* it must be aligned for storing doubles... */
     126:
     127: # ifndef BACKTEMP
     128:     OFFSZ t;
     129:
     130:     if( k>1 ){
     131:         SETOFF( tmpoff, ALDOUBLE );
     132:         }
     133:
     134:     t = tmpoff;
     135:     tmpoff += k*SZINT;
     136:     if( tmpoff > maxoff ) maxoff = tmpoff;
     137:     if( tmpoff >= offsz )
     138:         cerror("stack overflow" );
     139:     if( tmpoff-baseoff > maxtemp ) maxtemp = tmpoff-baseoff;
     140:     return(t);
     141:
     142: # else
     143:     tmpoff += k*SZINT;
     144:     if( k>1 ) {
     145:         SETOFF( tmpoff, ALDOUBLE );
     146:         }
     147:     if( tmpoff > maxoff ) maxoff = tmpoff;
     148:     if( tmpoff >= offsz )
     149:         cerror("stack overflow" );
     150:     if( tmpoff-baseoff > maxtemp ) maxtemp = tmpoff-baseoff;
     151:     return( -tmpoff );
     152: # endif
     153:     }
     154:
     155: freereg( p, n ) NODE *p; {
     156:     /* allocate a register of type n */
     157:     /* p gives the type, if floating */
     158:
     159:     register j;
     160:
     161:     /* not general; means that only one register (the result) OK for call */
     162:     if( callop(p->in.op) ){
     163:         j = callreg(p);
     164:         if( usable( p, n, j ) ) return( j );
     165:         /* have allocated callreg first */
     166:         }
     167:     j = p->in.rall & ~MUSTDO;
     168:     if( j!=NOPREF && usable(p,n,j) ){ /* needed and not allocated */
     169:         return( j );
     170:         }
     171:     if( n&NAMASK ){
     172:         for( j=mina; j<=maxa; ++j ) if( rstatus[j]&STAREG ){
     173:             if( usable(p,n,j) ){
     174:                 return( j );
     175:                 }
     176:             }
     177:         }
     178:     else if( n &NBMASK ){
     179:         for( j=minb; j<=maxb; ++j ) if( rstatus[j]&STBREG ){
     180:             if( usable(p,n,j) ){
     181:                 return(j);
     182:                 }
     183:             }
     184:         }
     185:
     186:     return( -1 );
     187:     }
     188:
     189: # ifndef USABLE
     190: usable( p, n, r ) NODE *p; {
     191:     /* decide if register r is usable in tree p to satisfy need n */
     192:
     193:     /* checks, for the moment */
     194:     if( !istreg(r) ) cerror("usable asked about nontemp register" );
     195:
     196:     if( busy[r] > 1 ) return(0);
     197:     if( isbreg(r) ){
     198:         if( n&NAMASK ) return(0);
     199:         }
     200:     else {
     201:         if( n & NBMASK ) return(0);
     202:         }
     203:     /*
     204: 	 * Some special cases that require register pairs...
     205: 	 * Have to check for ==, <=, etc. because the result is type int
     206: 	 * but need a register pair temp if either side is wide.
     207: 	 * For +=, *= etc. where lhs is narrow and rhs is wide, the temp
     208: 	 * register must be wide.
     209: 	 */
     210:     if( (n&NAMASK) &&
     211:         (szty(p->in.type) == 2 ||
     212:          (logop(p->in.op) && (szty(p->in.left->in.type) == 2 ||
     213:           szty(p->in.right->in.type) == 2)) ||
     214:          (asgop(p->in.op) && szty(p->in.right->in.type) == 2 &&
     215:           szty(p->in.left->in.type) == 1))
     216:     ){
     217: #ifndef NOEVENODD
     218:         if( r&01 ) return(0);
     219: #endif
     220:         if( !istreg(r+1) ) return( 0 );
     221:         if( busy[r+1] > 1 ) return( 0 );
     222:         if( busy[r] == 0 && busy[r+1] == 0  ||
     223:             busy[r+1] == 0 && shareit( p, r, n ) ||
     224:             busy[r] == 0 && shareit( p, r+1, n ) ){
     225:             busy[r] |= TBUSY;
     226:             busy[r+1] |= TBUSY;
     227:             return(1);
     228:             }
     229:         else return(0);
     230:         }
     231:     if( busy[r] == 0 ) {
     232:         busy[r] |= TBUSY;
     233:         return(1);
     234:         }
     235:
     236:     /* busy[r] is 1: is there chance for sharing */
     237:     return( shareit( p, r, n ) );
     238:
     239:     }
     240: # endif
     241:
     242: shareit( p, r, n ) NODE *p; {
     243:     /* can we make register r available by sharing from p
     244: 	   given that the need is n */
     245:     if( (n&(NASL|NBSL)) && ushare( p, 'L', r ) ) return(1);
     246:     if( (n&(NASR|NBSR)) && ushare( p, 'R', r ) ) return(1);
     247:     return(0);
     248:     }
     249:
     250: ushare( p, f, r ) NODE *p; {
     251:     /* can we find a register r to share on the left or right
     252: 		(as f=='L' or 'R', respectively) of p */
     253:     p = getlr( p, f );
     254:     if( p->in.op == UNARY MUL ) p = p->in.left;
     255:     if( p->in.op == OREG ){
     256:         if( R2TEST(p->tn.rval) ){
     257:             return( r==R2UPK1(p->tn.rval) || r==R2UPK2(p->tn.rval) );
     258:             }
     259:         else return( r == p->tn.rval );
     260:         }
     261:     if( p->in.op == REG ){
     262:         return( r == p->tn.rval || ( szty(p->in.type) == 2 && r==p->tn.rval+1 ) );
     263:         }
     264:     return(0);
     265:     }
     266:
     267: recl2( p ) register NODE *p; {
     268:     register r = p->tn.rval;
     269: #ifndef OLD
     270:     int op = p->in.op;
     271:     if (op == REG && r >= REGSZ)
     272:         op = OREG;
     273:     if( op == REG ) rfree( r, p->in.type );
     274:     else if( op == OREG ) {
     275:         if( R2TEST( r ) ) {
     276:             if( R2UPK1( r ) != 100 ) rfree( R2UPK1( r ), PTR+INT );
     277:             rfree( R2UPK2( r ), INT );
     278:             }
     279:         else {
     280:             rfree( r, PTR+INT );
     281:             }
     282:         }
     283: #else
     284:     if( p->in.op == REG ) rfree( r, p->in.type );
     285:     else if( p->in.op == OREG ) {
     286:         if( R2TEST( r ) ) {
     287:             if( R2UPK1( r ) != 100 ) rfree( R2UPK1( r ), PTR+INT );
     288:             rfree( R2UPK2( r ), INT );
     289:             }
     290:         else {
     291:             rfree( r, PTR+INT );
     292:             }
     293:         }
     294: #endif
     295:     }
     296:
     297: int rdebug = 0;
     298:
     299: # ifndef RFREE
     300: rfree( r, t ) TWORD t; {
     301:     /* mark register r free, if it is legal to do so */
     302:     /* t is the type */
     303:
     304: # ifndef BUG3
     305:     if( rdebug ){
     306:         printf( "rfree( %s ), size %d\n", rnames[r], szty(t) );
     307:         }
     308: # endif
     309:
     310:     if( istreg(r) ){
     311:         if( --busy[r] < 0 ) cerror("register overfreed");
     312:         if( szty(t) == 2 ){
     313: #ifdef NOEVENODD
     314:             if( istreg(r) ^ istreg(r+1) ) cerror("illegal free" );
     315: #else
     316:             if( (r&01) || (istreg(r)^istreg(r+1)) ) cerror("illegal free" );
     317: #endif
     318:             if( --busy[r+1] < 0 ) cerror("register overfreed" );
     319:             }
     320:         }
     321:     }
     322: # endif
     323:
     324: # ifndef RBUSY
     325: rbusy(r,t) TWORD t; {
     326:     /* mark register r busy */
     327:     /* t is the type */
     328:
     329: # ifndef BUG3
     330:     if( rdebug ){
     331:         printf( "rbusy( %s ), size %d\n", rnames[r], szty(t) );
     332:         }
     333: # endif
     334:
     335:     if( istreg(r) ) ++busy[r];
     336:     if( szty(t) == 2 ){
     337:         if( istreg(r+1) ) ++busy[r+1];
     338: #ifdef NOEVENODD
     339:         if( istreg(r) ^ istreg(r+1) ) cerror("illegal register pair freed" );
     340: #else
     341:         if( (r&01) || (istreg(r)^istreg(r+1)) ) cerror("illegal register pair freed" );
     342: #endif
     343:         }
     344:     }
     345: # endif
     346:
     347: # ifndef BUG3
     348: rwprint( rw ){ /* print rewriting rule */
     349:     register i, flag;
     350:     static char * rwnames[] = {
     351:
     352:         "RLEFT",
     353:         "RRIGHT",
     354:         "RESC1",
     355:         "RESC2",
     356:         "RESC3",
     357:         0,
     358:         };
     359:
     360:     if( rw == RNULL ){
     361:         printf( "RNULL" );
     362:         return;
     363:         }
     364:
     365:     if( rw == RNOP ){
     366:         printf( "RNOP" );
     367:         return;
     368:         }
     369:
     370:     flag = 0;
     371:     for( i=0; rwnames[i]; ++i ){
     372:         if( rw & (1<<i) ){
     373:             if( flag ) printf( "|" );
     374:             ++flag;
     375:             printf( rwnames[i] );
     376:             }
     377:         }
     378:     }
     379: # endif
     380:
     381: reclaim( p, rw, cookie ) NODE *p; {
     382:     register NODE **qq;
     383:     register NODE *q;
     384:     register i;
     385:     NODE *recres[5];
     386:     struct respref *r;
     387:
     388:     /* get back stuff */
     389:
     390: # ifndef BUG3
     391:     if( rdebug ){
     392:         printf( "reclaim( %o, ", p );
     393:         rwprint( rw );
     394:         printf( ", " );
     395:         prcook( cookie );
     396:         printf( " )\n" );
     397:         }
     398: # endif
     399:
     400:     if( rw == RNOP || ( p->in.op==FREE && rw==RNULL ) ) return;  /* do nothing */
     401:
     402:     walkf( p, recl2 );
     403:
     404:     if( callop(p->in.op) ){
     405:         /* check that all scratch regs are free */
     406:         callchk(p);  /* ordinarily, this is the same as allchk() */
     407:         }
     408:
     409:     if( rw == RNULL || (cookie&FOREFF) ){ /* totally clobber, leaving nothing */
     410:         tfree(p);
     411:         return;
     412:         }
     413:
     414:     /* handle condition codes specially */
     415:
     416:     if( (cookie & FORCC) && (rw&RESCC)) {
     417:         /* result is CC register */
     418:         tfree(p);
     419:         p->in.op = CCODES;
     420:         p->tn.lval = 0;
     421:         p->tn.rval = 0;
     422:         return;
     423:         }
     424:
     425:     /* locate results */
     426:
     427:     qq = recres;
     428:
     429:     if( rw&RLEFT) *qq++ = getlr( p, 'L' );
     430:     if( rw&RRIGHT ) *qq++ = getlr( p, 'R' );
     431:     if( rw&RESC1 ) *qq++ = &resc[0];
     432:     if( rw&RESC2 ) *qq++ = &resc[1];
     433:     if( rw&RESC3 ) *qq++ = &resc[2];
     434:
     435:     if( qq == recres ){
     436:         cerror("illegal reclaim");
     437:         }
     438:
     439:     *qq = NIL;
     440:
     441:     /* now, select the best result, based on the cookie */
     442:
     443:     for( r=respref; r->cform; ++r ){
     444:         if( cookie & r->cform ){
     445:             for( qq=recres; (q= *qq) != NIL; ++qq ){
     446:                 if( tshape( q, r->mform ) ) goto gotit;
     447:                 }
     448:             }
     449:         }
     450:
     451:     /* we can't do it; die */
     452:     cerror("cannot reclaim");
     453:
     454:     gotit:
     455:
     456:     if( p->in.op == STARG ) p = p->in.left;  /* STARGs are still STARGS */
     457:
     458:     q->in.type = p->in.type;  /* to make multi-register allocations work */
     459:         /* maybe there is a better way! */
     460:     q = tcopy(q);
     461:
     462:     tfree(p);
     463:
     464:     p->in.op = q->in.op;
     465:     p->tn.lval = q->tn.lval;
     466:     p->tn.rval = q->tn.rval;
     467: #ifdef FLEXNAMES
     468:     p->in.name = q->in.name;
     469: #ifdef ONEPASS
     470:     p->in.stalign = q->in.stalign;
     471: #endif
     472: #else
     473:     for( i=0; i<NCHNAM; ++i )
     474:         p->in.name[i] = q->in.name[i];
     475: #endif
     476:
     477:     q->in.op = FREE;
     478:
     479:     /* if the thing is in a register, adjust the type */
     480:
     481:     switch( p->in.op ){
     482:
     483:     case REG:
     484:         if( !rtyflg ){
     485:             /* the C language requires intermediate results to change type */
     486:             /* this is inefficient or impossible on some machines */
     487:             /* the "T" command in match supresses this type changing */
     488:             if( p->in.type == CHAR || p->in.type == SHORT ) p->in.type = INT;
     489:             else if( p->in.type == UCHAR || p->in.type == USHORT ) p->in.type = UNSIGNED;
     490: #if !defined(FORT) && !defined(SPRECC)
     491:             else if( p->in.type == FLOAT ) p->in.type = DOUBLE;
     492: #endif
     493:             }
     494:         if( ! (p->in.rall & MUSTDO ) ) return;  /* unless necessary, ignore it */
     495:         i = p->in.rall & ~MUSTDO;
     496:         if( i & NOPREF ) return;
     497:         if( i != p->tn.rval ){
     498:             if( busy[i] || ( szty(p->in.type)==2 && busy[i+1] ) ){
     499:                 cerror("faulty register move" );
     500:                 }
     501:             rbusy( i, p->in.type );
     502:             rfree( p->tn.rval, p->in.type );
     503:             rmove( i, p->tn.rval, p->in.type );
     504:             p->tn.rval = i;
     505:             }
     506:
     507:     case OREG:
     508:         if( p->in.op == REG || !R2TEST(p->tn.rval) ) {
     509:             if( busy[p->tn.rval]>1 && istreg(p->tn.rval) ) cerror("potential register overwrite");
     510:             }
     511:         else
     512:             if( (R2UPK1(p->tn.rval) != 100 && busy[R2UPK1(p->tn.rval)]>1 && istreg(R2UPK1(p->tn.rval)) )
     513:                 || (busy[R2UPK2(p->tn.rval)]>1 && istreg(R2UPK2(p->tn.rval)) ) )
     514:                cerror("potential register overwrite");
     515:         }
     516:
     517:     }
     518:
     519: #ifndef ncopy
     520: ncopy( q, p ) NODE *p, *q; {
     521:     /* copy the contents of p into q, without any feeling for
     522: 	   the contents */
     523:     /* this code assume that copying rval and lval does the job;
     524: 	   in general, it might be necessary to special case the
     525: 	   operator types */
     526:     register i;
     527:
     528:     q->in.op = p->in.op;
     529:     q->in.rall = p->in.rall;
     530:     q->in.type = p->in.type;
     531:     q->tn.lval = p->tn.lval;
     532:     q->tn.rval = p->tn.rval;
     533: #ifdef FLEXNAMES
     534:     q->in.name = p->in.name;
     535: #ifdef ONEPASS
     536:     q->in.stalign = p->in.stalign;
     537: #endif
     538: #else
     539:     for( i=0; i<NCHNAM; ++i ) q->in.name[i]  = p->in.name[i];
     540: #endif
     541:
     542:     }
     543: #endif
     544:
     545: NODE *
     546: tcopy( p ) register NODE *p; {
     547:     /* make a fresh copy of p */
     548:
     549:     register NODE *q;
     550:     register r;
     551:
     552:     ncopy( q=talloc(), p );
     553:
     554:     r = p->tn.rval;
     555:     if( p->in.op == REG ) rbusy( r, p->in.type );
     556:     else if( p->in.op == OREG ) {
     557:         if( R2TEST(r) ){
     558:             if( R2UPK1(r) != 100 ) rbusy( R2UPK1(r), PTR+INT );
     559:             rbusy( R2UPK2(r), INT );
     560:             }
     561:         else {
     562:             rbusy( r, PTR+INT );
     563:             }
     564:         }
     565:
     566:     switch( optype(q->in.op) ){
     567:
     568:     case BITYPE:
     569:         q->in.right = tcopy(p->in.right);
     570:     case UTYPE:
     571:         q->in.left = tcopy(p->in.left);
     572:         }
     573:
     574:     return(q);
     575:     }
     576:
     577: allchk(){
     578:     /* check to ensure that all register are free */
     579:
     580:     register i;
     581:
     582:     REGLOOP(i){
     583:         if( istreg(i) && busy[i] ){
     584:             cerror("register allocation error");
     585:             }
     586:         }
     587:
     588:     }

#### Defined functions

allchk defined in line 577; used 4 times

- in /usr/src/lib/mip/fort.c line 266
- in /usr/src/lib/mip/pass2.h line 192
- in /usr/src/lib/mip/reader.c line 210, 244

allo defined in line 36; used 1 times

- in /usr/src/lib/mip/match.c line 306

allo0 defined in line 14; used 1 times

- in /usr/src/lib/mip/reader.c line 46

freereg defined in line 155; used 2 times

- in line 47, 69

freetemp defined in line 122; used 3 times

- in line 37, 92-95(2)

ncopy defined in line 520; used 5 times

- in line 519, 552
- in /usr/src/lib/mip/reader.c line 315, 363, 566

rbusy defined in line 325; used 9 times

- in line 501, 555-562(4)
- in /usr/src/lib/mip/fort.c line 226, 240
- in /usr/src/lib/mip/reader.c line 1120
- in /usr/src/lib/mip/trees.c line 1684

recl2 defined in line 267; used 1 times

- in line 402

reclaim defined in line 381; used 10 times

- in /usr/src/lib/mip/fort.c line 264
- in /usr/src/lib/mip/match.c line 311
- in /usr/src/lib/mip/reader.c line 208, 243, 589, 678, 695, 740, 966, 1027

rfree defined in line 300; used 9 times

- in line 273-291(8), 502

rwprint defined in line 348; used 1 times

- in line 393

shareit defined in line 242; used 3 times

- in line 223-224(2), 237

tcopy defined in line 545; used 7 times

- in line 460, 569-571(2)
- in /usr/src/lib/mip/pass2.h line 175
- in /usr/src/lib/mip/reader.c line 360, 677, 693

usable defined in line 190; used 4 times

- in line 164-173(3), 180

ushare defined in line 250; used 2 times

- in line 245-246(2)

#### Defined variables

busy defined in line 9; used 22 times

- in line 22, 111, 196, 221-232(9), 311, 318, 335-337(2), 498(2), 509-513(3), 583

maxa defined in line 11; used 4 times

- in line 18, 24-25(2), 172

maxb defined in line 11; used 4 times

- in line 18, 28-29(2), 179

mina defined in line 11; used 3 times

- in line 19-24(2), 172

minb defined in line 11; used 3 times

- in line 19, 28, 179

rdebug defined in line 297; used 4 times

- in line 305, 330, 391
- in /usr/src/lib/mip/reader.c line 72

resc defined in line 7; used 24 times

- in line 46-52(5), 60, 68-74(5), 81, 89-103(8), 114, 431-433(3)

sccsid defined in line 2; never used

Last modified: 1995-01-18 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1902 |