Annotation of researchv8dc/cmd/ccom/common/cgen.c, revision 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.