Annotation of 3BSD/cmd/mip/allo.c, revision 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: 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( !istreg(r+1) ) return( 0 );
        !           158:                if( busy[r+1] > 1 ) return( 0 );
        !           159:                if( busy[r] == 0 && busy[r+1] == 0  ||
        !           160:                    busy[r+1] == 0 && shareit( p, r, n ) ||
        !           161:                    busy[r] == 0 && shareit( p, r+1, n ) ||
        !           162:                    shareit( p, r, n ) && 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:                        if( R2UPK1( r ) != 100 ) 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( (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( (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++ = p->left;
        !           331:        if( rw&RRIGHT ) *qq++ = p->right;
        !           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:        q->type = p->type==FLOAT && q->op==REG ? DOUBLE : p->type;
        !           361:                /* maybe there is a better way! */
        !           362:        q = tcopy(q);
        !           363: 
        !           364:        tfree(p);
        !           365: 
        !           366:        p->op = q->op;
        !           367:        p->lval = q->lval;
        !           368:        p->rval = q->rval;
        !           369:        for( i=0; i<NCHNAM; ++i )
        !           370:                p->name[i] = q->name[i];
        !           371: 
        !           372:        q->op = FREE;
        !           373: 
        !           374:        /* if the thing is in a register, adjust the type */
        !           375: 
        !           376:        switch( p->op ){
        !           377: 
        !           378:        case REG:
        !           379:                if( p->type == CHAR || p->type == SHORT ) p->type = INT;
        !           380:                else if( p->type == UCHAR || p->type == USHORT ) p->type = UNSIGNED;
        !           381:                else if( p->type == FLOAT ) p->type = DOUBLE;
        !           382:                if( ! (p->rall & MUSTDO ) ) return;  /* unless necessary, ignore it */
        !           383:                i = p->rall & ~MUSTDO;
        !           384:                if( i & NOPREF ) return;
        !           385:                if( i != p->rval ){
        !           386:                        if( busy[i] || ( szty(p->type)==2 && busy[i+1] ) ){
        !           387:                                cerror( "faulty register move" );
        !           388:                                }
        !           389:                        rbusy( i, p->type );
        !           390:                        rfree( p->rval, p->type );
        !           391:                        rmove( i, p->rval, p->type );
        !           392:                        p->rval = i;
        !           393:                        }
        !           394: 
        !           395:        case OREG:
        !           396:                if( p->op == REG || !R2TEST(p->rval) ) {
        !           397:                        if( busy[p->rval]>1 && istreg(p->rval) ) cerror( "potential register overwrite");
        !           398:                        }
        !           399:                else
        !           400:                        if( (R2UPK1(p->rval) != 100 && busy[R2UPK1(p->rval)]>1 && istreg(R2UPK1(p->rval)) )
        !           401:                                || (busy[R2UPK2(p->rval)]>1 && istreg(R2UPK2(p->rval)) ) )
        !           402:                           cerror( "potential register overwrite");
        !           403:                }
        !           404: 
        !           405:        }
        !           406: 
        !           407: ncopy( q, p ) NODE *p, *q; {
        !           408:        /* copy the contents of p into q, without any feeling for
        !           409:           the contents */
        !           410:        /* this code assume that copying rval and lval does the job;
        !           411:           in general, it might be necessary to special case the
        !           412:           operator types */
        !           413:        register i;
        !           414: 
        !           415:        q->op = p->op;
        !           416:        q->rall = p->rall;
        !           417:        q->type = p->type;
        !           418:        q->lval = p->lval;
        !           419:        q->rval = p->rval;
        !           420:        for( i=0; i<NCHNAM; ++i ) q->name[i]  = p->name[i];
        !           421: 
        !           422:        }
        !           423: 
        !           424: NODE *
        !           425: tcopy( p ) register NODE *p; {
        !           426:        /* make a fresh copy of p */
        !           427: 
        !           428:        register NODE *q;
        !           429:        register r;
        !           430: 
        !           431:        ncopy( q=talloc(), p );
        !           432: 
        !           433:        r = p->rval;
        !           434:        if( p->op == REG ) rbusy( r, p->type );
        !           435:        else if( p->op == OREG ) {
        !           436:                if( R2TEST(r) ){
        !           437:                        if( R2UPK1(r) != 100 ) rbusy( R2UPK1(r), PTR+INT );
        !           438:                        rbusy( R2UPK2(r), INT );
        !           439:                        }
        !           440:                else {
        !           441:                        rbusy( r, PTR+INT );
        !           442:                        }
        !           443:                }
        !           444: 
        !           445:        switch( optype(q->op) ){
        !           446: 
        !           447:        case BITYPE:
        !           448:                q->right = tcopy(p->right);
        !           449:        case UTYPE:
        !           450:                q->left = tcopy(p->left);
        !           451:                }
        !           452: 
        !           453:        return(q);
        !           454:        }
        !           455: 
        !           456: allchk(){
        !           457:        /* check to ensure that all register are free */
        !           458: 
        !           459:        register i;
        !           460: 
        !           461:        REGLOOP(i){
        !           462:                if( istreg(i) && busy[i] ){
        !           463:                        cerror( "register allocation error");
        !           464:                        }
        !           465:                }
        !           466: 
        !           467:        }

unix.superglobalmegacorp.com

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