Annotation of researchv8dc/cmd/ccom/common/cgen.c, revision 1.1.1.1

1.1       root        1: /*     @(#) cgen.c: 1.2 1/12/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, 0 );
                    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:        t = p->tn.type;
                    303:        if( t == TCHAR || t == TSHORT ) t = TINT;
                    304:        else if( t == TUCHAR || t == TUSHORT ) t = TUNSIGNED;
                    305:        else if( t == TFLOAT ) t = TDOUBLE;
                    306:        else return( p );
                    307: 
                    308:        if( p->tn.op == CONV && c2bigger(p) ) 
                    309:        {
                    310:                p->tn.type = t;
                    311:                return( p );
                    312:        }
                    313:        q = talloc();
                    314:        q->tn.op = CONV;
                    315:        q->in.left = p;
                    316:        q->in.right = 0;
                    317:        q->tn.name = (char *) 0;
                    318:        q->tn.type = t;
                    319:        q->tn.goal = NRGS;
                    320:        return( q );
                    321: }
                    322: 
                    323: NODE *
                    324: reweop( p )
                    325: register NODE *p; 
                    326: 
                    327: {
                    328:        /* rewrite A op= B as A = A op B */
                    329:        /* also, rewrite (CONV A) op= B as A = (CONV ( (CONV A) op B ) ) */
                    330:        /* rewritten in place */
                    331:        /* on input, the type of the op= equals the type of A */
                    332:        /* the type of the op node on output is the type of B */
                    333:        /* the type of the = node on output is the type of A */
                    334: 
                    335:        register NODE *q, *t;
                    336:        register TWORD ty;
                    337: 
                    338: #ifndef NODBG
                    339:        if( odebug>1 ) 
                    340:        {
                    341:                e2print( p );
                    342:                printf( "\nrewritten by reweop as:\n" );
                    343:        }
                    344: #endif
                    345:        q = tcopy( p, 0 );
                    346:        if( p->in.left->tn.op == CONV ) 
                    347:        {
                    348:                /* ( CONV (A) ) op= B becomes A = CONV ( CONV(A) op B ) */
                    349:                /* the op is done to the type of B */
                    350:                /* the assignment is done to the type of A */
                    351:                t = p->in.left;
                    352:                ty = t->in.left->tn.type;
                    353:                p->in.left = t->in.left;
                    354:                tfree( p->in.right );
                    355:                p->in.right = t;
                    356:                t->in.left = q;
                    357:                /* now, have the tree built; fix the types */
                    358:                t->tn.type = ty;
                    359:        }
                    360:        else 
                    361:        {
                    362:                tfree( p->in.right );
                    363:                p->in.right = q;
                    364:        }
                    365:        /* NOTE: no =ops for structures... */
                    366:        p->tn.op = ASSIGN;
                    367:        q->tn.op = NOASG q->tn.op;
                    368:        p->tn.type = p->in.left->tn.type;
                    369:        q->tn.type = q->in.right->tn.type;
                    370: #ifndef NODBG
                    371:        if( odebug>1 ) e2print( p );
                    372: #endif
                    373: }
                    374: 
                    375: rewass( p )
                    376: NODE *p; 
                    377: 
                    378: {
                    379:        NODE *q;
                    380:        int o;
                    381:        /* look for =ops to be rewritten */
                    382: 
                    383: #ifndef NODBG
                    384:        if( odebug ) 
                    385:        {
                    386:                printf( "rewass called with:\n" );
                    387:                e2print( p );
                    388:        }
                    389: #endif
                    390:        o = p->tn.op;
                    391:        if( o == UNARY AND ) 
                    392:        {
                    393:                if( p->in.left->tn.op == RNODE ) 
                    394:                {
                    395:                        /* this should happen only with structure returns */
                    396:                        q = p->in.left;
                    397:                        q->tn.op = ICON;
                    398:                        *p = *q;
                    399:                        q->tn.op = FREE;
                    400:                        return(0);  /* keep going in costs */
                    401:                }
                    402:                /* this case should happen only with short structures */
                    403:                rewsto( p->in.left );
                    404:                /* & f() has turned into & ( t=f(),t) */
                    405: #ifndef NODBG
                    406:                if( odebug ) 
                    407:                {
                    408:                        printf( "\nrewritten by rewass as:\n" );
                    409:                        e2print( p );
                    410:                }
                    411: #endif
                    412:                return(1);
                    413:        }
                    414:        if( !asgop(o) || o==ASSIGN ) 
                    415:        {
                    416:                if( o==ASSIGN ) 
                    417:                {
                    418:                        /* look for funny nodes on lhs */
                    419:                        o = p->in.left->tn.op;
                    420:                        if( o==RNODE || o==QNODE || o==SNODE ) 
                    421:                        {
                    422:                                /* force into r0 */
                    423:                                p->in.left->tn.op = REG;
                    424:                                p->in.left->tn.rval = callreg( p->in.right );
                    425: #ifndef NODBG
                    426:                                if( odebug ) 
                    427:                                {
                    428:                                        printf( "funny node redone\n" );
                    429:                                        e2print(p);
                    430:                                }
                    431: #endif
                    432:                                return(0);
                    433:                        }
                    434:                }
                    435:                else 
                    436:                {
                    437:                        TWORD t = p->in.left->tn.type;
                    438:                        /* this case is, for example, 
                    439:                                unsigned char a, b;
                    440:                                ...   a*b
                    441:                        /* we convert both to a reasonable type */
                    442:                        /* the result is assumed to be automatically
                    443:                        /* converted downwards if it should be... */
                    444: 
                    445:                        p->in.left = ind2type( p->in.left );
                    446:                        p->in.right = ind2type( p->in.right );
                    447: #ifndef NODBG
                    448:                        if( odebug ) {
                    449:                                printf( "conversions inserted" );
                    450:                                e2print(p);
                    451:                        }
                    452: #endif
                    453:                        /* if this didn't work, we are in trouble */
                    454:                        if( t != p->in.left->tn.type ) {
                    455:                                /* we have changed something */
                    456:                                return( 0 );
                    457:                        }
                    458:                }
                    459:                e2print(p);
                    460:                cerror( "can't deal with op %s", opst[o] );
                    461:        }
                    462:        if( o == INCR || o == DECR ) 
                    463:        {
                    464:                /* very crude: a++ becomes (a+=1)-1 */
                    465: #ifndef NODBG
                    466:                if( odebug>1 ) 
                    467:                {
                    468:                        e2print( p );
                    469:                        printf( "\nrewritten by rewass as:\n" );
                    470:                }
                    471: #endif
                    472:                if( p->in.goal == CEFF )
                    473:                {
                    474:                        p->in.op = ((o==INCR)?ASG PLUS:ASG MINUS);
                    475:                }
                    476:                else
                    477:                {
                    478:                        q = tcopy(p, 0);
                    479:                        regrcl( p->in.left );
                    480:                        tfree( p->in.left );
                    481:                        p->in.left = q;
                    482:                        q->tn.op = ((o==INCR)?ASG PLUS:ASG MINUS);
                    483:                        p->tn.op = ((o==INCR)?MINUS:PLUS);
                    484:                }
                    485: #ifndef NODBG
                    486:                if( odebug ) 
                    487:                {
                    488:                        printf( "\nrewritten by rewass as:\n" );
                    489:                        e2print( p );
                    490:                }
                    491: #endif
                    492:                return(1);
                    493:        }
                    494:        /* find out if some subtree has to be stored into a temp... */
                    495:        if( q = lhsto(p) ) 
                    496:        {
                    497:                if( !rewsto( q ) ) cerror( "rewass0" );  /* q => t=q,t */
                    498:                rewcom( p, p->tn.goal );  /* move COMOP to the top */
                    499:                if( p->tn.op != COMOP ) cerror( "rewass1" );
                    500:                if( !asgop( p->in.right->tn.op ) ) cerror( "rewass2" );
                    501:                reweop( p->in.right );
                    502:        }
                    503:        else reweop( p );  /* rewrite p as an =OP */
                    504:        return(1);
                    505: }
                    506: 
                    507: # ifdef NONEST
                    508: subcall( p )
                    509: register NODE *p; 
                    510: 
                    511: {
                    512:        /* return 1 if p contains a callop */
                    513:        register o, t;
                    514: 
                    515:        o = p->tn.op;
                    516:        if( callop(o)
                    517: # ifndef UCALLBAD
                    518:            && o!=UNARY CALL
                    519: # endif
                    520: # ifndef STCALLBAD
                    521:            && o!=UNARY STCALL
                    522: # endif
                    523: # ifndef UFCALLBAD
                    524:            && o!=UNARY FORTCALL
                    525: # endif
                    526:            ) return( 1 );
                    527:        t = optype( o );
                    528:        if( t==BITYPE && subcall(p->in.right) ) return( 1 );
                    529:        if( t!=LTYPE ) return( subcall( p->in.left ) );
                    530:        return( 0 );
                    531: }
                    532: 
                    533: nonest( p )
                    534: register NODE *p; 
                    535: 
                    536: {
                    537:        register o, t;
                    538:        /* right now, this is very crude */
                    539:        /* find arguments below a call; store them */
                    540:        /* nonest is called up to a call; stocm is called within args */
                    541: 
                    542:        o = p->tn.op;
                    543:        t = optype( o );
                    544:        if( o==CALL || o==STCALL || o==FORTCALL) 
                    545:        {
                    546:                stocm( p->in.right );
                    547:                nonest( p->in.left );
                    548:                return;
                    549:        }
                    550:        if( t == BITYPE ) nonest( p->in.right );
                    551:        if( t != LTYPE ) nonest( p->in.left );
                    552: }
                    553: 
                    554: stocm( p )
                    555: register NODE *p; 
                    556: 
                    557: {
                    558:        /* all call arguments below p must be stored */
                    559:        register NODE *q;
                    560:        register o;
                    561: 
                    562:        while( (o=p->tn.op) == CM )
                    563:        {
                    564:                stocm( p->in.right );
                    565:                p = p->in.left;
                    566:        }
                    567:        if( o != STARG && o != FUNARG ) cerror( "stocm" );
                    568: 
                    569:        q = p->in.left;
                    570:        if( subcall( q ) ) 
                    571:        {
                    572:                if( o == FUNARG ) rewsto( q );
                    573:                else 
                    574:                {
                    575:                        /* structure argument with call beneath */
                    576:                        rewsto( p );
                    577:                }
                    578:                /* now q will be done outside of a call, so use nonest */
                    579:                nonest( q );
                    580:        }
                    581: }
                    582: # endif
                    583: 
                    584: outshp( pp )
                    585: SHAPE **pp; 
                    586: 
                    587: {
                    588:        SHAPE *p;
                    589: 
                    590:        if (pp == 0)
                    591:                return;
                    592: 
                    593:        for( ; p = *pp; ++pp )
                    594:        {
                    595:                printf("\t\t");
                    596:                shpr(p);
                    597:                printf( " (%d)\n", p->sc );
                    598:        }
                    599: }
                    600: 
                    601: tabpr()
                    602: {
                    603:        register        OPTAB   *p;
                    604:        for (p =table; ;p++)
                    605:        {
                    606:                printf("Dump of table[%d] (stinline %d)\n", p-table, p->stinline );
                    607:                printf("\top = %s\n", opst[p->op]);
                    608:                printf("\tnextop = %d\n", p->nextop?p->nextop-table:-1 );
                    609:                printf("\tlshape = %d\n", p->lshape-pshape);
                    610:                printf("\tltype = 0%o\n", p->ltype);
                    611:                printf("\trshape = %d\n", p->rshape-pshape);
                    612:                printf("\trtype = 0%o\n", p->rtype);
                    613:                printf("\tneeds = %d\n", p->needs);
                    614:                printf("\trewrite = %d\n", p->rewrite);
                    615:                printf("\tcstring = %s", p->cstring);
                    616:                printf("\tcost = %d\n", p->cost);
                    617:                printf("\tLeft:\n");
                    618:                outshp(p->lshape);
                    619:                printf("\tRight:\n");
                    620:                outshp(p->rshape);
                    621:                printf("\n");
                    622:        }
                    623: }
                    624: 
                    625: codgen( p )
                    626: NODE *p; 
                    627: 
                    628: {
                    629: 
                    630:        /* generate the code for p; */
                    631:        int i, flag;
                    632: 
                    633: #ifndef NODBG
                    634:        if (odebug > 5)
                    635:        {
                    636:                tabpr();
                    637:                /* NOTREACHED */
                    638:        }
                    639: #endif
                    640: 
                    641: # ifdef NONEST
                    642:        nonest(p);
                    643: # endif
                    644: 
                    645:        /* if we make drastic changes to the tree (e.g., introduce temps)
                    646:        ** /* we will go back and do the whole thing again 
                    647:        */
                    648:        /* statistics indicate that this happens about 10% of the time */
                    649:        /* if the percentage rises, there are many things that can be done to
                    650:        ** /* improve matters 
                    651:        */
                    652:        /* for example, RNODE, etc., could be removed by reader, and some of
                    653:        ** /* the op rewriting could be discovered by reader as well 
                    654:        */
                    655: 
                    656: again:
                    657: 
                    658:        /* move the comma ops as high as practical */
                    659: 
                    660:        rewcom( p, CEFF );
                    661: 
                    662: #ifndef NODBG
                    663:        if( odebug ) 
                    664:        {
                    665:                printf( "After goals are computed:" );
                    666:                e2print( p );
                    667:        }
                    668: #endif
                    669: 
                    670:        /* compute the costs */
                    671: 
                    672:        if( costs( p ) ) goto again;  /* if rewritten, do again */
                    673: 
                    674: #ifndef NODBG
                    675:        if( odebug ) 
                    676:        {
                    677:                printf( "After costs are computed:" );
                    678:                e2print( p );
                    679:        }
                    680: #endif
                    681: 
                    682:        /* do a trial code generation */
                    683:        nins = 0;
                    684:        insout( p, CEFF );
                    685: 
                    686:        /* rewrite stored subtrees as assignments to temps, with COMOP's */
                    687:        flag = 0;
                    688:        for( i=0; i<nins; ++i ) 
                    689:        {
                    690:                if( inst[i].goal == CTEMP ) 
                    691:                {
                    692: #ifndef NODBG
                    693:                        if( odebug ) 
                    694:                        {
                    695:                                printf( "subtree is stored in temp:\n" );
                    696:                                e2print( inst[i].p );
                    697:                        }
                    698: #endif
                    699:                        if( rewsto( inst[i].p ) ) {
                    700:                                if( !fast ) goto again;
                    701:                                /* otherwise, rewrite all temps now */
                    702:                                flag = 1;
                    703:                        }
                    704:                }
                    705:        }
                    706:        if( flag ) goto again;
                    707: 
                    708: #ifndef NODBG
                    709:        if( odebug ) e2print(p);
                    710: #endif
                    711:        /* output the actual instructions */
                    712:        insprt();
                    713: }
                    714: 
                    715: INST inst[NINS];
                    716: int nins;
                    717: 
                    718: insprt()
                    719: {
                    720:        int i;
                    721:        register INST *pi;
                    722:        register NODE *p;
                    723:        register OPTAB *q;
                    724:        register c, goal;
                    725: 
                    726:        for( pi=inst,i=0; i<nins; ++i,++pi )
                    727:        {
                    728:                p = pi->p;
                    729:                q = pi->q;
                    730:                c = pi->goal;
                    731:                if( c == CCC && (q->rewrite&RESCC) ) goal = FORCC;
                    732:                else if( c == CEFF ) goal = FOREFF;
                    733:                else goal = INREG;
                    734: #ifndef NODEBUG
                    735:                if(odebug > 4)
                    736:                {
                    737:                        printf("INSOUT: %d c=",i);
                    738:                        preff(c);
                    739:                        printf(" goal=");
                    740:                        prgoal(goal);
                    741:                        printf("\n");
                    742:                        e2print(p);
                    743:                }
                    744: #endif
                    745: 
                    746:                allo( p, q );
                    747: # ifdef TMPSRET
                    748:                /* not the best place in the world, but... */
                    749:                if (p->in.op == STCALL || p->in.op == UNARY STCALL)
                    750:                        expand(p, goal, TMPSRET, q);
                    751: #endif
                    752:                expand( p, goal, q->cstring, q );
                    753:                reclaim( p, q->rewrite, goal );
                    754: 
                    755:                /* now, if condition codes needed, test */
                    756:                if( c == CCC && p->tn.op != CCODES ) 
                    757:                {
                    758:                        cfix( p, CCC );
                    759:                        if( p->tn.op != CCODES ) cerror( "ctest fails" );
                    760:                }
                    761:                if( c>=0 && c<=NRGS && !istnode( p ) )
                    762:                {
                    763:                        cfix( p, NRGS );
                    764:                }
                    765:        }
                    766: }
                    767: 
                    768: SHTABLE sha;
                    769: 
                    770: cfix( p, goal )
                    771: NODE *p; 
                    772: {
                    773:        /* p is to be fixed according to goal (CCC or NRGS) */
                    774:        OPTAB *q;
                    775:        NODE *pp;
                    776:        int r;
                    777: 
                    778: #ifndef NODBG
                    779:        if(odebug > 4)
                    780:        {
                    781:                printf("CFIX: goal=");
                    782:                prgoal(goal);
                    783:                printf("\n");
                    784:                e2print(p);
                    785:        }
                    786: #endif
                    787:        if( goal == CCC ) 
                    788:        {
                    789:                r = RESCC;
                    790:                p->tn.goal = CCC;
                    791:        }
                    792:        else 
                    793:        {
                    794:                r = (RESC1|RESC2|RESC3);
                    795:                pp = getl( p );
                    796:                if( istnode( pp ) ) r |= RLEFT;
                    797:                pp = getr( p );
                    798:                if( istnode( pp ) ) r |= RRIGHT;
                    799:        }
                    800: 
                    801:        if( goal == CCC ) goal = FORCC;
                    802:        else goal = INREG;
                    803: 
                    804:        for( q=0; q = match( p, q ); )
                    805:        {
                    806:                /* takes the first match (may not be cheapest) */
                    807:                /* template writers, take note! */
                    808:                if( q->rewrite & r ) 
                    809:                {
                    810:                        /* generate the code on the spot */
                    811:                        allo( p, q );
                    812: # ifdef TMPSRET
                    813:                        /* likewise */
                    814:                        if (p->in.op == STCALL || p->in.op == UNARY STCALL)
                    815:                                expand(p, goal, TMPSRET, q);
                    816: #endif
                    817:                        expand( p, goal, q->cstring, q );
                    818:                        reclaim( p, q->rewrite, goal );
                    819:                        return;
                    820:                }
                    821:        }
                    822:        e2print(p);
                    823:        cerror( "cfix trouble" );
                    824: }
                    825: 
                    826: 
                    827: preff(c)
                    828: {
                    829:        char buf[20];
                    830:        register char *p;
                    831: 
                    832:        p = c==CCC ? "CCC" : c==CTEMP ? "CTEMP" : c==CEFF ? "CEFF" : 0;
                    833:        if(!p)
                    834:        {
                    835:                sprintf(buf,"0%o",c);
                    836:                p = buf;
                    837:        }
                    838:        printf("%s",p);
                    839: }

unix.superglobalmegacorp.com

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