Annotation of researchv9/jerq/sgs/comp/cgen.c, revision 1.1.1.1

1.1       root        1: /*     @(#) cgen.c: 1.3 4/26/84        */
                      2: 
                      3: # include "mfile2.h"
                      4: # define istnode(p) (p->in.op==REG && istreg(p->tn.rval))
                      5: 
                      6: /*
                      7: ** For God's workes are, like him, all infinite
                      8: ** And curious search but craftie sin's delight.
                      9: */
                     10: 
                     11: rewcom( p, goal )
                     12: NODE *p; 
                     13: 
                     14: {
                     15:        /* find all , ops, move as high as is legal */
                     16:        /* rewrite p in place; this takes some doing! */
                     17:        /* while we are at it, take care of setting the goal field */
                     18:        int o, ty, g1, g2;
                     19:        NODE *l, *r, *ql, *qr;
                     20: 
                     21:        o = p->tn.op;
                     22:        g1 = g2 = NRGS;
                     23:        p->tn.goal = goal;
                     24: 
                     25:        /* special cases for subtrees:
                     26:        ** GENBR has left as Condition codes
                     27:        ** COMOP has left as Effects
                     28:        ** COLON, GENUBR, CM, GENLAB have descendents = node
                     29:        ** CALL, STCALL, FORTCALL has right as Effects
                     30:        ** All others use registers
                     31:        */
                     32: 
                     33:        switch( o )
                     34:        {
                     35: 
                     36:        case FREE:
                     37:                cerror( "rewcom(%d) is FREE", p-node );
                     38: 
                     39:        case GENBR:
                     40:                g1 = CCC;
                     41:                break;
                     42: 
                     43:        case COMOP:
                     44:                g1 = CEFF;
                     45:                g2 = goal;
                     46:                break;
                     47: 
                     48:        case COLON:
                     49:        case GENUBR:
                     50:        case CM:
                     51:        case GENLAB:
                     52:                g1 = g2 = goal;
                     53:                break;
                     54: 
                     55:        case CALL:
                     56:        case STCALL:
                     57:        case FORTCALL:
                     58:                g2 = CEFF;
                     59:                break;
                     60:        }
                     61: 
                     62: 
                     63:        switch( ty = optype(o) )
                     64:        {
                     65: 
                     66:        case BITYPE:
                     67:                rewcom( r = p->in.right, g2 );
                     68:        case UTYPE:
                     69:                rewcom( l = p->in.left, g1 );
                     70:                break;
                     71:        case LTYPE:
                     72:                return;
                     73:        }
                     74: 
                     75:        if( o==COMOP || o==COLON || o==GENLAB ) return;
                     76: 
                     77:        /* look for (A,B) op C and A op (B,C), and rewrite */
                     78:        /* A,B if A headed by GENBR can't be rewritten */
                     79:        /* the assumption is that B is executed immediately after A, */
                     80:        /* and this won't necessarily be true if op is commutative */
                     81: 
                     82:        if( l->tn.op == COMOP && l->in.left->tn.op != GENBR ) 
                     83:        {
                     84:                /* rewrite it... */
                     85:                /* (A,B) op C => A,(B op C) */
                     86:                /* also, for unary ops,  op (A,B) => A , (op B)  */
                     87:                ql = l->in.left;
                     88:                qr = l->in.right;
                     89:                *l = *p;  /* copies op, and other stuff if op is unary */
                     90:                l->in.left = qr;
                     91:                p->in.right = l;
                     92:                p->in.left = ql;
                     93:                p->tn.op = COMOP;
                     94:                rewcom( p, p->tn.goal );
                     95:        }
                     96:        if( ty == UTYPE ) return;
                     97:        if( r->tn.op == COMOP && r->in.right->tn.op != GENBR ) 
                     98:        {
                     99:                /* rewrite, again */
                    100:                /* A op (B,C) => B,(A op C) */
                    101:                /* op is not unary now */
                    102:                ql = r->in.left;
                    103:                qr = r->in.right;
                    104:                *r = *p;
                    105:                p->tn.op = COMOP;
                    106:                p->in.left = ql;
                    107:                r->in.right = qr;
                    108:                rewcom( p, p->tn.goal );
                    109:        }
                    110: }
                    111: 
                    112: rewlhs(p)
                    113: NODE *p; 
                    114: 
                    115: {
                    116:        /* rewrite x op= y as (x op= y),x */
                    117:        /* it would be really nice to optimize after doing this . . . */
                    118:        NODE *q, *t;
                    119:        q = talloc();
                    120:        *q = *p;
                    121:        t = tcopy( p->in.left );
                    122:        p->in.left = q;
                    123:        p->in.right = t;
                    124:        p->tn.op = COMOP;
                    125:        return;
                    126: }
                    127: 
                    128: rewsto(p)
                    129: NODE *p; 
                    130: {
                    131:        /* a temp, t, is generated, and p is rewritten as ((t=p),t) */
                    132:        /* if p has the form x op= A, and x is of the right form, rewrite
                    133:        /* as ((x op= A), x) */
                    134: 
                    135:        int o, ao;
                    136:        NODE *t, *q;
                    137:        /* probably not perfect for structs: CHECK UP.. */
                    138: 
                    139:        while( (o=p->tn.op) == COMOP ) p = p->in.right;
                    140:        if( o == TEMP ) return(0);  /* nothing to do */
                    141:        if( o == STARG ) 
                    142:        {
                    143:                 /* store a structure argument */               /* like storing a usual argument, but we have addresses */
                    144: 
                    145:                t = talloc();
                    146:                *t = *p->in.left;  /* copy contents, mainly for type, etc. */
                    147:                q = talloc();
                    148:                *q = *t;
                    149:                t->tn.op = TEMP;
                    150:                t->tn.lval = freetemp(argsize(p)/SZINT );
                    151:                t->tn.lval = BITOOR(t->tn.lval);
                    152:                t->tn.name = (char *) 0;
                    153:                t->tn.type = TSTRUCT;
                    154:                q->tn.op = UNARY AND;
                    155:                q->in.left = t;
                    156:                /* now, q has & TEMP */
                    157:                t = talloc();
                    158:                *t = *p;
                    159:                t->in.left = q;
                    160:                t->in.right = p->in.left;
                    161:                t->tn.op = STASG;
                    162:                /* now, t has (&TEMP) = struct */
                    163:                p->in.left = talloc();
                    164:                p->in.left->tn.op = COMOP;
                    165:                p->in.left->in.left = t;
                    166:                p->in.left->in.right = t = talloc(); /* copy q here */
                    167:                *t = *q;
                    168:                t->in.left = talloc();
                    169:                *t->in.left = *q->in.left;
                    170:                /* finally, have (&TEMP = struct),(&TEMP) */
                    171:                /* this should do it: whew! */
                    172: #ifndef NODBG
                    173:                if( odebug>1 ) e2print( p );
                    174: #endif
                    175:                return( 1 );
                    176:        }
                    177: 
                    178: #ifndef NODBG
                    179:        if( odebug>1 ) 
                    180:        {
                    181:                e2print( p );
                    182:                printf( "\nrewritten by rewsto as:\n" );
                    183:        }
                    184: #endif
                    185:        if( asgop(o) && o!=INCR && o!=DECR && lhsok( p->in.left ) ) {
                    186:                /* x op= y turns into (x op= y), x */
                    187:                rewlhs( p );
                    188:                return( 1 );
                    189:        }
                    190:        ao = ASG o;
                    191:        if( asgbinop(ao) ) 
                    192:        {
                    193:                if( p->in.left->tn.op == TEMP ) 
                    194:                {
                    195:                        p->tn.op = ao;
                    196:                        rewlhs( p );
                    197: #ifndef NODBG
                    198:                        if( odebug>1 ) e2print( p );
                    199: #endif
                    200:                        return( 1 );
                    201:                }
                    202:        }
                    203: 
                    204:        /* to rewrite in place, p becomes a COMOP; rhs is the temp, lsh
                    205:        ** /* is t = p, where p has been converted to the intermediate type 
                    206:        */
                    207:        /* after some debate, the type of the temp will be the type of p */
                    208: 
                    209:        t = talloc();
                    210:        *t = *p;  /* copy contents, mainly for type, etc. */
                    211:        q = talloc();
                    212:        *q = *p;
                    213:        t->tn.op = TEMP;
                    214:        t->tn.lval = freetemp(argsize(p)/SZINT );
                    215:        t->tn.lval = BITOOR(t->tn.lval);
                    216:        t->tn.name = (char *) 0;
                    217:        q->tn.op = ASSIGN;
                    218:        q->in.left = t;
                    219:        q->in.right = talloc();
                    220:        *(q->in.right) = *p;
                    221:                /* now, q has (t=p) */
                    222:        p->in.right = talloc();
                    223:        *(p->in.right) = *t;
                    224:        p->tn.op = COMOP;
                    225:        p->in.left = q;
                    226:        /* this should do it: whew! */
                    227: #ifndef NODBG
                    228:        if( odebug>1 ) e2print( p );
                    229: #endif
                    230:        return( 1 );
                    231: }
                    232: 
                    233: iseff( p )
                    234: NODE *p; 
                    235: 
                    236: {
                    237:        /* return 1 if p has some side effects, 0 otherwise */
                    238:        int o;
                    239:        o = p->tn.op;
                    240:        if( callop(o) || asgop(o) ) return( 1 );
                    241:        switch( optype( o ) )
                    242:        {
                    243:        case BITYPE:
                    244:                if( iseff( p->in.right ) ) return( 1 );
                    245:        case UTYPE:
                    246:                return( iseff( p->in.left ) );
                    247:        }
                    248:        return( 0 );
                    249: }
                    250: 
                    251: NODE *
                    252: lhsto( p )
                    253: NODE *p; 
                    254: 
                    255: {
                    256:        /* find a piece of the LHS to be stored */
                    257:        /* if found, rewrite tree */
                    258:        NODE *q;
                    259:        int o;
                    260: 
                    261:        for( q = p->in.left; (o=q->tn.op)!=STAR; q=q->in.left )
                    262:        {
                    263:                if( optype(o) == LTYPE ) return( (NODE *)0);
                    264:        }
                    265:        /* q is now the * node, if there one */
                    266:        q = q->in.left;
                    267:        o = q->tn.op;
                    268:        if( optype(o) == LTYPE ) return( (NODE *)0 );
                    269:        else return( q );
                    270: }
                    271: 
                    272: static int
                    273: c2bigger( p ) NODE *p; {
                    274:        /* p is a conversion op; does it make things bigger */
                    275:        register TWORD t, tl;
                    276: 
                    277:        t = p->tn.type;
                    278:        tl = p->in.left->tn.type;
                    279: 
                    280:        if( (t|tl)&TPOINT ) return( 0 );  /* pointers are funny */
                    281:        if( t&TDOUBLE ) return( 1 );
                    282:        if( tl&TDOUBLE ) return( 0 );
                    283:        if( t&TFLOAT ) return( 1 );
                    284:        if( tl&TFLOAT ) return( 0 );
                    285:        if( t&(TLONG|TULONG) ) return( 1 );
                    286:        if( tl&(TLONG|TULONG) ) return( 0 );
                    287:        if( t&(TINT|TUNSIGNED) ) return( 1 );
                    288:        if( tl&(TINT|TUNSIGNED) ) return( 0 );
                    289:        if( t &(TSHORT|TUSHORT) ) return( 1 );
                    290:        return( 0 );
                    291:        }
                    292: 
                    293: NODE *
                    294: ind2type( p )
                    295: register NODE *p; 
                    296: 
                    297: {
                    298:        /* make the type of p be the appropriate type for an argument */
                    299:        register TWORD t;
                    300:        NODE *q;
                    301: 
                    302:        if ( !p )
                    303:                return( p );
                    304:        t = p->tn.type;
                    305:        if( t == TCHAR || t == TSHORT ) t = TINT;
                    306:        else if( t == TUCHAR || t == TUSHORT ) t = TUNSIGNED;
                    307:        else if( t == TFLOAT ) t = TDOUBLE;
                    308:        else return( p );
                    309: 
                    310:        if( p->tn.op == CONV && c2bigger(p) ) 
                    311:        {
                    312:                p->tn.type = t;
                    313:                return( p );
                    314:        }
                    315:        q = talloc();
                    316:        q->tn.op = CONV;
                    317:        q->in.left = p;
                    318:        q->in.right = 0;
                    319:        q->tn.name = (char *) 0;
                    320:        q->tn.type = t;
                    321:        q->tn.goal = NRGS;
                    322:        return( q );
                    323: }
                    324: 
                    325: NODE *
                    326: reweop( p )
                    327: register NODE *p; 
                    328: 
                    329: {
                    330:        /* rewrite A op= B as A = A op B */
                    331:        /* also, rewrite (CONV A) op= B as A = (CONV ( (CONV A) op B ) ) */
                    332:        /* rewritten in place */
                    333:        /* on input, the type of the op= equals the type of A */
                    334:        /* the type of the op node on output is the type of B */
                    335:        /* the type of the = node on output is the type of A */
                    336: 
                    337:        register NODE *q, *t;
                    338:        register TWORD ty;
                    339: 
                    340: #ifndef NODBG
                    341:        if( odebug>1 ) 
                    342:        {
                    343:                e2print( p );
                    344:                printf( "\nrewritten by reweop as:\n" );
                    345:        }
                    346: #endif
                    347:        /* rewrite tree with duplicate left subtree in new right subtree */
                    348:        /* there is an implicit q->in.right = p->in.right in  *q = *p */
                    349:        q = talloc();
                    350:        *q = *p;        
                    351:        q->in.left = tcopy( p->in.left );
                    352:        if( p->in.left->tn.op == CONV ) 
                    353:        {
                    354:                /* ( CONV (A) ) op= B becomes A = CONV ( CONV(A) op B ) */
                    355:                /* the op is done to the type of B */
                    356:                /* the assignment is done to the type of A */
                    357:                t = p->in.left;
                    358:                ty = t->in.left->tn.type;
                    359:                p->in.left = t->in.left;
                    360:                p->in.right = t;
                    361:                t->in.left = q;
                    362:                /* now, have the tree built; fix the types */
                    363:                t->tn.type = ty;
                    364:        }
                    365:        else 
                    366:        {
                    367:                p->in.right = q;
                    368:        }
                    369:        /* NOTE: no =ops for structures... */
                    370:        p->tn.op = ASSIGN;
                    371:        q->tn.op = NOASG q->tn.op;
                    372:        p->tn.type = p->in.left->tn.type;
                    373:        q->tn.type = q->in.right->tn.type;
                    374: #ifndef NODBG
                    375:        if( odebug>1 ) e2print( p );
                    376: #endif
                    377: }
                    378: 
                    379: rewass( p )
                    380: NODE *p; 
                    381: 
                    382: {
                    383:        NODE *q;
                    384:        int o;
                    385:        /* look for =ops to be rewritten */
                    386: 
                    387: #ifndef NODBG
                    388:        if( odebug ) 
                    389:        {
                    390:                printf( "rewass called with:\n" );
                    391:                e2print( p );
                    392:        }
                    393: #endif
                    394:        o = p->tn.op;
                    395:        if( o == UNARY AND ) 
                    396:        {
                    397:                if( p->in.left->tn.op == RNODE ) 
                    398:                {
                    399:                        /* this should happen only with structure returns */
                    400:                        q = p->in.left;
                    401:                        q->tn.op = ICON;
                    402:                        *p = *q;
                    403:                        q->tn.op = FREE;
                    404:                        return(0);  /* keep going in costs */
                    405:                }
                    406:                /* this case should happen only with short structures */
                    407:                rewsto( p->in.left );
                    408:                /* & f() has turned into & ( t=f(),t) */
                    409: #ifndef NODBG
                    410:                if( odebug ) 
                    411:                {
                    412:                        printf( "\nrewritten by rewass as:\n" );
                    413:                        e2print( p );
                    414:                }
                    415: #endif
                    416:                return(1);
                    417:        }
                    418:        if( !asgop(o) || o==ASSIGN ) 
                    419:        {
                    420:                if( o==ASSIGN ) 
                    421:                {
                    422:                        /* look for funny nodes on lhs */
                    423:                        o = p->in.left->tn.op;
                    424:                        if( o==RNODE || o==QNODE || o==SNODE ) 
                    425:                        {
                    426:                                /* force into r0 */
                    427:                                p->in.left->tn.op = REG;
                    428:                                p->in.left->tn.rval = callreg( p->in.right );
                    429: #ifndef NODBG
                    430:                                if( odebug ) 
                    431:                                {
                    432:                                        printf( "funny node redone\n" );
                    433:                                        e2print(p);
                    434:                                }
                    435: #endif
                    436:                                return(0);
                    437:                        }
                    438:                }
                    439:                else 
                    440:                {
                    441:                        TWORD t = p->in.left->tn.type;
                    442:                        /* this case is, for example, 
                    443:                                unsigned char a, b;
                    444:                                ...   a*b
                    445:                        /* we convert both to a reasonable type */
                    446:                        /* the result is assumed to be automatically
                    447:                        /* converted downwards if it should be... */
                    448: 
                    449:                        p->in.left = ind2type( p->in.left );
                    450:                        p->in.right = ind2type( p->in.right );
                    451: #ifndef NODBG
                    452:                        if( odebug ) {
                    453:                                printf( "conversions inserted" );
                    454:                                e2print(p);
                    455:                        }
                    456: #endif
                    457:                        /* if this didn't work, we are in trouble */
                    458:                        if( t != p->in.left->tn.type ) {
                    459:                                /* we have changed something */
                    460:                                return( 0 );
                    461:                        }
                    462:                }
                    463:                e2print(p);
                    464:                cerror( "can't deal with op %s", opst[o] );
                    465:        }
                    466:        if( o == INCR || o == DECR ) 
                    467:        {
                    468:                /* very crude: a++ becomes (a+=1)-1 */
                    469: #ifndef NODBG
                    470:                if( odebug>1 ) 
                    471:                {
                    472:                        e2print( p );
                    473:                        printf( "\nrewritten by rewass as:\n" );
                    474:                }
                    475: #endif
                    476:                if( p->in.goal == CEFF )
                    477:                {
                    478:                        p->in.op = ((o==INCR)?ASG PLUS:ASG MINUS);
                    479:                }
                    480:                else
                    481:                {
                    482:                        /* rewrite tree with duplicate left subree in new
                    483:                        /* right subtree...
                    484:                        /* there is an implict q->in.left = p->in.left in *q = * p
                    485:                        */
                    486:                        q = talloc();
                    487:                        *q = *p;        
                    488:                        q->in.right = tcopy( p->in.right );
                    489:                        p->in.left = q;
                    490:                        q->tn.op = ((o==INCR)?ASG PLUS:ASG MINUS);
                    491:                        p->tn.op = ((o==INCR)?MINUS:PLUS);
                    492:                }
                    493: #ifndef NODBG
                    494:                if( odebug ) 
                    495:                {
                    496:                        printf( "\nrewritten by rewass as:\n" );
                    497:                        e2print( p );
                    498:                }
                    499: #endif
                    500:                return(1);
                    501:        }
                    502:        /* find out if some subtree has to be stored into a temp... */
                    503:        if( q = lhsto(p) ) 
                    504:        {
                    505:                if( !rewsto( q ) ) cerror( "rewass0" );  /* q => t=q,t */
                    506:                rewcom( p, p->tn.goal );  /* move COMOP to the top */
                    507:                if( p->tn.op != COMOP ) cerror( "rewass1" );
                    508:                if( !asgop( p->in.right->tn.op ) ) cerror( "rewass2" );
                    509:                reweop( p->in.right );
                    510:        }
                    511:        else reweop( p );  /* rewrite p as an =OP */
                    512:        return(1);
                    513: }
                    514: 
                    515: # ifdef NONEST
                    516: subcall( p )
                    517: register NODE *p; 
                    518: 
                    519: {
                    520:        /* return 1 if p contains a callop */
                    521:        register o, t;
                    522: 
                    523:        o = p->tn.op;
                    524:        if( callop(o)
                    525: # ifndef UCALLBAD
                    526:            && o!=UNARY CALL
                    527: # endif
                    528: # ifndef STCALLBAD
                    529:            && o!=UNARY STCALL
                    530: # endif
                    531: # ifndef UFCALLBAD
                    532:            && o!=UNARY FORTCALL
                    533: # endif
                    534:            ) return( 1 );
                    535:        t = optype( o );
                    536:        if( t==BITYPE && subcall(p->in.right) ) return( 1 );
                    537:        if( t!=LTYPE ) return( subcall( p->in.left ) );
                    538:        return( 0 );
                    539: }
                    540: 
                    541: nonest( p )
                    542: register NODE *p; 
                    543: 
                    544: {
                    545:        register o, t;
                    546:        /* right now, this is very crude */
                    547:        /* find arguments below a call; store them */
                    548:        /* nonest is called up to a call; stocm is called within args */
                    549: 
                    550:        o = p->tn.op;
                    551:        t = optype( o );
                    552:        if( o==CALL || o==STCALL || o==FORTCALL) 
                    553:        {
                    554:                stocm( p->in.right );
                    555:                nonest( p->in.left );
                    556:                return;
                    557:        }
                    558:        if( t == BITYPE ) nonest( p->in.right );
                    559:        if( t != LTYPE ) nonest( p->in.left );
                    560: }
                    561: 
                    562: stocm( p )
                    563: register NODE *p; 
                    564: 
                    565: {
                    566:        /* all call arguments below p must be stored */
                    567:        register NODE *q;
                    568:        register o;
                    569: 
                    570:        while( (o=p->tn.op) == CM )
                    571:        {
                    572:                stocm( p->in.right );
                    573:                p = p->in.left;
                    574:        }
                    575:        if( o != STARG && o != FUNARG ) cerror( "stocm" );
                    576: 
                    577:        q = p->in.left;
                    578:        if( subcall( q ) ) 
                    579:        {
                    580:                if( o == FUNARG ) rewsto( q );
                    581:                else 
                    582:                {
                    583:                        /* structure argument with call beneath */
                    584:                        rewsto( p );
                    585:                }
                    586:                /* now q will be done outside of a call, so use nonest */
                    587:                nonest( q );
                    588:        }
                    589: }
                    590: # endif
                    591: 
                    592: outshp( pp )
                    593: SHAPE **pp; 
                    594: 
                    595: {
                    596:        SHAPE *p;
                    597: 
                    598:        if (pp == 0)
                    599:                return;
                    600: 
                    601:        for( ; p = *pp; ++pp )
                    602:        {
                    603:                printf("\t\t");
                    604:                shpr(p);
                    605:                printf( " (%d)\n", p->sc );
                    606:        }
                    607: }
                    608: 
                    609: tabpr()
                    610: {
                    611:        register        OPTAB   *p;
                    612:        for (p =table; ;p++)
                    613:        {
                    614:                printf("Dump of table[%d] (stinline %d)\n", p-table, p->stinline );
                    615:                printf("\top = %s\n", opst[p->op]);
                    616:                printf("\tnextop = %d\n", p->nextop?p->nextop-table:-1 );
                    617:                printf("\tlshape = %d\n", p->lshape-pshape);
                    618:                printf("\tltype = 0%o\n", p->ltype);
                    619:                printf("\trshape = %d\n", p->rshape-pshape);
                    620:                printf("\trtype = 0%o\n", p->rtype);
                    621:                printf("\tneeds = %d\n", p->needs);
                    622:                printf("\trewrite = %d\n", p->rewrite);
                    623:                printf("\tcstring = %s", p->cstring);
                    624:                printf("\tcost = %d\n", p->cost);
                    625:                printf("\tLeft:\n");
                    626:                outshp(p->lshape);
                    627:                printf("\tRight:\n");
                    628:                outshp(p->rshape);
                    629:                printf("\n");
                    630:        }
                    631: }
                    632: 
                    633: codgen( p )
                    634: NODE *p; 
                    635: 
                    636: {
                    637: 
                    638:        /* generate the code for p; */
                    639:        int i, flag;
                    640: 
                    641: #ifndef NODBG
                    642:        if (odebug > 5)
                    643:        {
                    644:                tabpr();
                    645:                /* NOTREACHED */
                    646:        }
                    647: #endif
                    648: 
                    649: # ifdef NONEST
                    650:        nonest(p);
                    651: # endif
                    652: 
                    653:        /* if we make drastic changes to the tree (e.g., introduce temps)
                    654:        ** /* we will go back and do the whole thing again 
                    655:        */
                    656:        /* statistics indicate that this happens about 10% of the time */
                    657:        /* if the percentage rises, there are many things that can be done to
                    658:        ** /* improve matters 
                    659:        */
                    660:        /* for example, RNODE, etc., could be removed by reader, and some of
                    661:        ** /* the op rewriting could be discovered by reader as well 
                    662:        */
                    663: 
                    664: again:
                    665: 
                    666:        /* move the comma ops as high as practical */
                    667: 
                    668:        rewcom( p, CEFF );
                    669: 
                    670: #ifndef NODBG
                    671:        if( odebug ) 
                    672:        {
                    673:                printf( "After goals are computed:" );
                    674:                e2print( p );
                    675:        }
                    676: #endif
                    677: 
                    678:        /* compute the costs */
                    679: 
                    680:        if( costs( p ) ) goto again;  /* if rewritten, do again */
                    681: 
                    682: #ifndef NODBG
                    683:        if( odebug ) 
                    684:        {
                    685:                printf( "After costs are computed:" );
                    686:                e2print( p );
                    687:        }
                    688: #endif
                    689: 
                    690:        /* do a trial code generation */
                    691:        nins = 0;
                    692:        insout( p, CEFF );
                    693: 
                    694:        /* rewrite stored subtrees as assignments to temps, with COMOP's */
                    695:        flag = 0;
                    696:        for( i=0; i<nins; ++i ) 
                    697:        {
                    698:                if( inst[i].goal == CTEMP ) 
                    699:                {
                    700: #ifndef NODBG
                    701:                        if( odebug ) 
                    702:                        {
                    703:                                printf( "subtree is stored in temp:\n" );
                    704:                                e2print( inst[i].p );
                    705:                        }
                    706: #endif
                    707:                        if( rewsto( inst[i].p ) ) {
                    708:                                if( !fast ) goto again;
                    709:                                /* otherwise, rewrite all temps now */
                    710:                                flag = 1;
                    711:                        }
                    712:                }
                    713:        }
                    714:        if( flag ) goto again;
                    715: 
                    716: #ifndef NODBG
                    717:        if( odebug ) e2print(p);
                    718: #endif
                    719:        /* output the actual instructions */
                    720:        insprt();
                    721: }
                    722: 
                    723: INST inst[NINS];
                    724: int nins;
                    725: 
                    726: insprt()
                    727: {
                    728:        int i;
                    729:        register INST *pi;
                    730:        register NODE *p;
                    731:        register OPTAB *q;
                    732:        register c, goal;
                    733: 
                    734:        for( pi=inst,i=0; i<nins; ++i,++pi )
                    735:        {
                    736:                p = pi->p;
                    737:                q = pi->q;
                    738:                c = pi->goal;
                    739:                if( c == CCC && (q->rewrite&RESCC) ) goal = FORCC;
                    740:                else if( c == CEFF ) goal = FOREFF;
                    741:                else goal = INREG;
                    742: #ifndef NODEBUG
                    743:                if(odebug > 4)
                    744:                {
                    745:                        printf("INSOUT: %d c=",i);
                    746:                        preff(c);
                    747:                        printf(" goal=");
                    748:                        prgoal(goal);
                    749:                        printf("\n");
                    750:                        e2print(p);
                    751:                }
                    752: #endif
                    753: 
                    754:                allo( p, q );
                    755: # ifdef TMPSRET
                    756:                /* not the best place in the world, but... */
                    757:                if (p->in.op == STCALL || p->in.op == UNARY STCALL)
                    758:                        expand(p, goal, TMPSRET, q);
                    759: #endif
                    760:                expand( p, goal, q->cstring, q );
                    761:                reclaim( p, q->rewrite, goal );
                    762: 
                    763:                /* now, if condition codes needed, test */
                    764:                if( c == CCC && p->tn.op != CCODES ) 
                    765:                {
                    766:                        cfix( p, CCC );
                    767:                        if( p->tn.op != CCODES ) cerror( "ctest fails" );
                    768:                }
                    769:                if( c>=0 && c<=NRGS && !istnode( p ) )
                    770:                {
                    771:                        cfix( p, NRGS );
                    772:                }
                    773:        }
                    774: }
                    775: 
                    776: SHTABLE sha;
                    777: int odebug = 0;
                    778: 
                    779: cfix( p, goal )
                    780: NODE *p; 
                    781: {
                    782:        /* p is to be fixed according to goal (CCC or NRGS) */
                    783:        OPTAB *q;
                    784:        NODE *pp;
                    785:        int r;
                    786: 
                    787: #ifndef NODBG
                    788:        if(odebug > 4)
                    789:        {
                    790:                printf("CFIX: goal=");
                    791:                prgoal(goal);
                    792:                printf("\n");
                    793:                e2print(p);
                    794:        }
                    795: #endif
                    796:        if( goal == CCC ) 
                    797:        {
                    798:                r = RESCC;
                    799:                p->tn.goal = CCC;
                    800:        }
                    801:        else 
                    802:        {
                    803:                r = (RESC1|RESC2|RESC3);
                    804:                pp = getl( p );
                    805:                if( istnode( pp ) ) r |= RLEFT;
                    806:                pp = getr( p );
                    807:                if( istnode( pp ) ) r |= RRIGHT;
                    808:        }
                    809: 
                    810:        if( goal == CCC ) goal = FORCC;
                    811:        else goal = INREG;
                    812: 
                    813:        for( q=0; q = match( p, q ); )
                    814:        {
                    815:                /* takes the first match (may not be cheapest) */
                    816:                /* template writers, take note! */
                    817:                if( q->rewrite & r ) 
                    818:                {
                    819:                        /* generate the code on the spot */
                    820:                        allo( p, q );
                    821: # ifdef TMPSRET
                    822:                        /* likewise */
                    823:                        if (p->in.op == STCALL || p->in.op == UNARY STCALL)
                    824:                                expand(p, goal, TMPSRET, q);
                    825: #endif
                    826:                        expand( p, goal, q->cstring, q );
                    827:                        reclaim( p, q->rewrite, goal );
                    828:                        return;
                    829:                }
                    830:        }
                    831:        e2print(p);
                    832:        cerror( "cfix trouble" );
                    833: }
                    834: 
                    835: 
                    836: preff(c)
                    837: {
                    838:        char buf[20];
                    839:        register char *p;
                    840: 
                    841:        p = c==CCC ? "CCC" : c==CTEMP ? "CTEMP" : c==CEFF ? "CEFF" : 0;
                    842:        if(!p)
                    843:        {
                    844:                sprintf(buf,"0%o",c);
                    845:                p = buf;
                    846:        }
                    847:        printf("%s",p);
                    848: }

unix.superglobalmegacorp.com

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