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

Defined functions

allchk defined in line 575; used 4 times
allo defined in line 36; used 1 times
allo0 defined in line 14; used 1 times
freereg defined in line 153; used 2 times
freetemp defined in line 121; used 2 times
ncopy defined in line 518; used 5 times
rbusy defined in line 323; used 9 times
recl2 defined in line 265; used 1 times
reclaim defined in line 379; used 10 times
rfree defined in line 298; used 9 times
rwprint defined in line 346; used 1 times
shareit defined in line 240; used 3 times
tcopy defined in line 543; used 7 times
usable defined in line 188; used 4 times
ushare defined in line 248; used 2 times

Defined variables

busy defined in line 9; used 22 times
maxa defined in line 11; used 4 times
maxb defined in line 11; used 4 times
mina defined in line 11; used 3 times
minb defined in line 11; used 3 times
rdebug defined in line 295; used 4 times
resc defined in line 7; used 24 times
sccsid defined in line 2; never used
Last modified: 1986-01-11
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2210
Valid CSS Valid XHTML 1.0 Strict