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

Defined functions

allchk defined in line 462; used 3 times
allo defined in line 31; used 1 times
allo0 defined in line 9; used 1 times
freereg defined in line 109; used 2 times
freetemp defined in line 81; used 2 times
ncopy defined in line 413; used 4 times
rbusy defined in line 237; used 8 times
recl2 defined in line 204; used 1 times
reclaim defined in line 284; used 10 times
rfree defined in line 220; used 5 times
rwprint defined in line 252; used 1 times
shareit defined in line 179; used 3 times
tcopy defined in line 430; used 6 times
usable defined in line 143; used 4 times
ushare defined in line 187; used 2 times

Defined variables

busy defined in line 5; used 22 times
maxa defined in line 7; used 4 times
maxb defined in line 7; used 4 times
mina defined in line 7; used 3 times
minb defined in line 7; used 3 times
rdebug defined in line 218; used 3 times

Defined macros

TBUSY defined in line 29; used 4 times

Usage of this include

allo.c used 1 times
Last modified: 1981-07-10
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 953
Valid CSS Valid XHTML 1.0 Strict