Annotation of researchv9/jerq/sgs/comp/cgen.c, revision 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.