Annotation of researchv9/cmd/sun/mip/allo.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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