Annotation of 43BSDTahoe/lib/mip/allo.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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