Annotation of cci/usr/src/lib/fmip/allo.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.