Annotation of researchv10no/cmd/ccom/common/reader.c, revision 1.1

1.1     ! root        1: /*     @(#) reader.c : 1.7 3/5/84      */
        !             2: 
        !             3: # include "mfile2.h"
        !             4: 
        !             5: /*     some storage declarations */
        !             6: 
        !             7: # ifdef TWOPASS
        !             8: NODE node[TREESZ];
        !             9: char ftitle[100] = "\"\"";  /* the name of the file */
        !            10: int ftnno;  /* number of current function */
        !            11: int lineno;
        !            12: #endif
        !            13: 
        !            14: int lflag;
        !            15: int e2debug;
        !            16: int udebug;
        !            17: int fast;
        !            18: 
        !            19: /* maxtemp is the maximum size (in bits) needed for temps so far */
        !            20: /* maxarg is ditto for outgoing arguments */
        !            21: /* maxboff is ditto for automatic variables */
        !            22: /* earlier attempts to keep these on a per-block basis were silly */
        !            23: int maxtemp;
        !            24: extern int maxarg;
        !            25: int maxboff;
        !            26: NODE *condit(), *prepass();
        !            27: 
        !            28: NODE *
        !            29: force(p)
        !            30: register NODE *p; 
        !            31: {
        !            32:        register NODE *q, *r;
        !            33:        if( !p ) cerror( "force" );
        !            34:        q = talloc();
        !            35:        *q = *p;
        !            36:        r = talloc();
        !            37:        *r = *p;
        !            38:        q->tn.op = ASSIGN;
        !            39:        q->in.right = p;
        !            40:        q->in.left = r;
        !            41:        r->tn.op = QNODE;
        !            42:        r->tn.rval = callreg(p); /* the reg where the value will be forced */
        !            43:        return( q );
        !            44: }
        !            45: 
        !            46: int odebug = 0, rdebug = 0, sdebug = 0;
        !            47: 
        !            48: p2init( argc, argv )
        !            49: char *argv[];
        !            50: {
        !            51:        /* set the values of the pass 2 arguments */
        !            52: 
        !            53:        register int c; extern int syncstdio;
        !            54:        register char *cp;
        !            55:        register files;
        !            56: 
        !            57:        allo0();  /* free all regs */
        !            58:        files = 0;
        !            59: 
        !            60:        for( c=1; c<argc; ++c )
        !            61:        {
        !            62:                if( *(cp=argv[c]) == '-' )
        !            63:                {
        !            64:                        while( *++cp )
        !            65:                        {
        !            66:                                switch(++syncstdio, *cp)
        !            67:                                {
        !            68: 
        !            69:                                case 'X':  /* pass1 flags */
        !            70:                                        while( *++cp ) 
        !            71:                                        {
        !            72:                                                 /* VOID */ 
        !            73:                                        }
        !            74:                                        --syncstdio;
        !            75:                                        --cp;
        !            76:                                        break;
        !            77: # ifdef GDEBUG
        !            78: #define LL_TOP 0       /* from mfile1.h */
        !            79:                                case 'g':  /* another stab in the back */
        !            80:                                        {
        !            81:                                                extern int gdebug;
        !            82:                                                extern int wloop_level, floop_level;
        !            83:                                                gdebug = !gdebug;
        !            84:                                                wloop_level = LL_TOP; /* natural */
        !            85:                                                floop_level = LL_TOP; /* loops */
        !            86:                                        }       /* fall through */
        !            87: # endif
        !            88:                                case 'l':  /* linenos */
        !            89:                                        --syncstdio;
        !            90:                                        ++lflag;
        !            91:                                        break;
        !            92: 
        !            93:                                case 'e':  /* expressions */
        !            94:                                        ++e2debug;
        !            95:                                        break;
        !            96: 
        !            97:                                case 'o':  /* orders */
        !            98:                                        ++odebug;
        !            99:                                        break;
        !           100: 
        !           101:                                case 'r':  /* register allocation */
        !           102:                                        ++rdebug;
        !           103:                                        break;
        !           104: 
        !           105:                                case 's':  /* shapes */
        !           106:                                        ++sdebug;
        !           107:                                        break;
        !           108: 
        !           109:                                case 'u':  /* Sethi-Ullman testing
        !           110:                                                (machine dependent) */
        !           111:                                        ++udebug;
        !           112:                                        break;
        !           113: 
        !           114:                                case 'f':  /* try for faster compile speed */
        !           115:                                        ++fast;
        !           116:                                        break;
        !           117: 
        !           118:                                default:
        !           119:                                        cerror( "bad option: %c", *cp );
        !           120:                                }
        !           121:                        }
        !           122:                }
        !           123:                else files = 1;  /* assumed to be a ftitle */
        !           124:        }
        !           125: 
        !           126:        mkdope();
        !           127:        return( files );
        !           128: }
        !           129: 
        !           130: NODE *
        !           131: dlabel( p, l )
        !           132: register NODE *p; 
        !           133: {
        !           134:        /* define a label after p is executed */
        !           135:        register NODE *q;
        !           136: 
        !           137: /*     condit will throw away things, fix here
        !           138: /*     if( !p ) cerror( "dlabel" );
        !           139: */
        !           140:        if (!p)         /* create conventional dumb subtree */
        !           141:        {
        !           142:                p = talloc();
        !           143:                p->tn.op = ICON;
        !           144:                p->tn.name = NULL;
        !           145:                p->tn.lval = 0;
        !           146:                p->tn.type = TINT;
        !           147:        }
        !           148:        q = talloc();
        !           149:        q->tn.type = p->tn.type;
        !           150:        q->in.left = p;
        !           151:        q->tn.op = GENLAB;
        !           152:        q->bn.label = l;
        !           153:        return( q );
        !           154: }
        !           155: 
        !           156: 
        !           157: NODE *
        !           158: genbr( o, l, p )
        !           159: register NODE *p; 
        !           160: register o,l;
        !           161: {
        !           162:        /* after evaluating p, generate a branch to l */
        !           163:        /* if o is 0, unconditional */
        !           164:        register NODE *q;
        !           165:        if( !p ) cerror( "genbr" );
        !           166:        if( l < 0 ) cerror( "genbr1" );
        !           167:        q = talloc();
        !           168:        q->tn.op = o?GENBR:GENUBR;
        !           169:        q->tn.type = p->tn.type;
        !           170:        q->in.left = p;
        !           171:        q->bn.label = l;
        !           172:        q->bn.lop = o;
        !           173:        if( o && logop(p->tn.op) &&
        !           174:                (p->tn.op != ANDAND) 
        !           175:                && (p->tn.op != OROR)
        !           176:        ) p->tn.op = CMP;
        !           177:        return( q );
        !           178: }
        !           179: 
        !           180: 
        !           181: static NODE *
        !           182: oreff(p)
        !           183: register NODE *p;
        !           184: {
        !           185:        register NODE *r, *l;
        !           186:        NODE *condit(), *seq();
        !           187:        int lab, t, f;
        !           188:        /* oreff is called if an || op is evaluated with goal=CEFF
        !           189:           The rhs of || ops should be executed only if the
        !           190:           lhs is false.  Since our goal is CEFF, we don't need
        !           191:           a result of the ||, but we need to
        !           192:           preserve that dependancy with this special case */
        !           193: 
        !           194:        /* We must catch this case before its children are
        !           195:           condit() and change the goal on it left child to CCC */
        !           196:           
        !           197:        if (tcond(p->in.left))  {
        !           198:                tfree(p->in.right);
        !           199:                p->in.op = FREE;
        !           200:                p = condit( p->in.left, CEFF, -1, -1);
        !           201:        } else if (fcond(p->in.left))  {
        !           202:                p->in.op = COMOP;
        !           203:                p = condit( p, CEFF, -1, -1);
        !           204:        } else {
        !           205:                lab = getlab();
        !           206:                l = condit( p->in.left, CCC, lab, -1);
        !           207:                r = condit( p->in.right, CEFF, -1, -1);
        !           208:                p->in.op = FREE;
        !           209:                p = seq(l, r);  /* put r after l */
        !           210:                p = dlabel(p, lab);
        !           211:        }
        !           212:        return p;
        !           213: }
        !           214: static NODE *
        !           215: andeff(p)
        !           216: register NODE *p;
        !           217: {
        !           218:        register NODE *r, *l;
        !           219:        NODE *condit();
        !           220:        int lab, t, f;
        !           221:        /* andeff is called if an && op is evaluated with goal=CEFF
        !           222:           The rhs of && ops should be executed only if the
        !           223:           lhs is true.  Since our goal is CEFF, we don't need
        !           224:           a result of the &&, but we need to
        !           225:           preserve that dependancy with this special case */
        !           226: 
        !           227:        /* We must catch this case before its children are
        !           228:           condit() and change the goal on it left child to CCC */
        !           229:           
        !           230:        if (fcond(p->in.left))  {
        !           231:                tfree(p->in.right);
        !           232:                p->in.op = FREE;
        !           233:                p = condit( p->in.left, CEFF, -1, -1);
        !           234:        } else if (tcond(p->in.left))  {
        !           235:                p->in.op = COMOP;
        !           236:                p = condit( p, CEFF, -1, -1);
        !           237:        } else {
        !           238:                lab = getlab();
        !           239:                p->in.op = FREE;
        !           240:                l = condit( p->in.left, CCC, -1, lab);
        !           241:                r = condit( p->in.right, CEFF, -1, -1);
        !           242:                p = seq(l, r);  /* put r after l */
        !           243:                p = dlabel(p, lab);
        !           244:        }
        !           245:        return p;
        !           246: }
        !           247: int negrel[] = 
        !           248: {
        !           249:         NE, EQ, GT, GE, LT, LE, UGT, UGE, ULT, ULE 
        !           250: } ;  /* negatives of relationals */
        !           251: 
        !           252: tcond( p )
        !           253: register NODE *p; 
        !           254: {
        !           255:        /* return 1 if p is always true, 0 otherwise */
        !           256:        register o = p->tn.op;
        !           257:        register NODE *q;
        !           258: 
        !           259:        switch( o ) 
        !           260:        {
        !           261: 
        !           262:        case ICON:
        !           263:                return( p->tn.lval || p->tn.name != (char *) 0 );
        !           264: 
        !           265:        case COMOP:
        !           266:                return( tcond( p->in.right ) );
        !           267: 
        !           268:        case ANDAND:
        !           269:                return( tcond( p->in.left ) && tcond( p->in.right ) );
        !           270: 
        !           271:        case OROR:
        !           272:                return( tcond( p->in.left ) || tcond( p->in.right ) );
        !           273: 
        !           274:        case NOT:
        !           275:                return( fcond( p->in.left ) );
        !           276: 
        !           277:        case QUEST:
        !           278:                q = p->in.right;
        !           279:                if( tcond( p->in.left ) ) return( tcond( q->in.left ) );
        !           280:                if( fcond( p->in.left ) ) return( tcond( q->in.right ) );
        !           281:                return( tcond( q->in.left ) && tcond( q->in.right ) );
        !           282: 
        !           283:        default:
        !           284:                return( 0 );
        !           285:        }
        !           286: }
        !           287: 
        !           288: fcond( p )
        !           289: register NODE *p; 
        !           290: {
        !           291:        /* return 1 if p is always false, 0 otherwise */
        !           292:        register o = p->tn.op;
        !           293:        register NODE *q;
        !           294: 
        !           295:        switch( o ) 
        !           296:        {
        !           297: 
        !           298:        case ICON:
        !           299:                return( !p->tn.lval && p->tn.name == (char *) 0 );
        !           300: 
        !           301:        case COMOP:
        !           302:                return( fcond( p->in.right ) );
        !           303: 
        !           304:        case ANDAND:
        !           305:                return( fcond( p->in.left ) || fcond( p->in.right ) );
        !           306: 
        !           307:        case OROR:
        !           308:                return( fcond( p->in.left ) && fcond( p->in.right ) );
        !           309: 
        !           310:        case NOT:
        !           311:                return( tcond( p->in.left ) );
        !           312: 
        !           313:        case QUEST:
        !           314:                q = p->in.right;
        !           315:                if( tcond( p->in.left ) ) return( fcond( q->in.left ) );
        !           316:                if( fcond( p->in.left ) ) return( fcond( q->in.right ) );
        !           317:                return( fcond( q->in.left ) && fcond( q->in.right ) );
        !           318: 
        !           319:        default:
        !           320:                return( 0 );
        !           321:        }
        !           322: }
        !           323: 
        !           324: NODE *
        !           325: rcomma( p )
        !           326: register NODE *p; 
        !           327: {
        !           328:        /* p is a COMOP; return the shrunken version thereof */
        !           329: 
        !           330:        if( p->tn.op != COMOP ) cerror( "rcomma" );
        !           331: 
        !           332:        if( p->in.left && p->in.right ) return( p );
        !           333:        p->tn.op = FREE;
        !           334:        if( !p->in.left ) return( p->in.right );
        !           335:        return( p->in.left );
        !           336: }
        !           337: 
        !           338: NODE *
        !           339: seq( p1, p2 )
        !           340: register NODE *p1, *p2;
        !           341: {
        !           342:        /* execute p then q */
        !           343:        register NODE *q;
        !           344: 
        !           345:        q = talloc();
        !           346:        if (!p1) return p2;
        !           347:        if (!p2) return p1;
        !           348:        q->in.op = COMOP;
        !           349:        /*q->in.type = p2->in.right->in.type; why? */
        !           350:        q->in.type = p2->in.type;
        !           351:        q->in.left = p1;
        !           352:        q->in.right = p2;
        !           353:        return q;
        !           354: }
        !           355: 
        !           356: NODE *
        !           357: gtb( p, l )
        !           358: register NODE *p; 
        !           359: register l;
        !           360: {
        !           361:        register NODE *q;
        !           362:        /* replace p by a trivial branch to l */
        !           363:        /* if l is -1, return NULL */
        !           364:        q = condit( p, CEFF, -1, -1 );
        !           365:        if( l<0 ) return( q );
        !           366:        if( !q ) 
        !           367:        {
        !           368:                q = talloc();
        !           369:                q->tn.op = ICON;
        !           370:                q->tn.lval = 0;
        !           371:                q->tn.name = (char *) 0;
        !           372:                q->tn.type = TINT;
        !           373:        }
        !           374:        return( genbr( 0, l, q ) );
        !           375: }
        !           376: 
        !           377: NODE *
        !           378: condit( p, goal, t, f )
        !           379: register NODE *p; 
        !           380: register goal,t,f;
        !           381: {
        !           382:        /* generate code for conditionals in terms of GENLAB and GENBR nodes */
        !           383:        /* goal is either CEFF, NRGS, or CCC */
        !           384:        /* also, delete stuff that never needs get done */
        !           385:        /* if goal==CEFF, return of null means nothing to be done */
        !           386: 
        !           387:        register o, lt, lf, l;
        !           388:        register NODE *q, *q1, *q2;
        !           389: 
        !           390:        o = p->tn.op;
        !           391: 
        !           392: #ifndef NODBG
        !           393:        if( odebug >2 ) 
        !           394:        {
        !           395:                printf( "condit( %d (%s), %s, %d, %d )\n", (int)(p-node),
        !           396:                opst[o], goal==CCC?"CCC":(goal==NRGS?"NRGS":"CEFF"),
        !           397:                t, f );
        !           398:        }
        !           399: #endif
        !           400:        if( o == CBRANCH ) 
        !           401:        {
        !           402:                p->in.right->tn.op = p->tn.op = FREE;
        !           403:                l = p->in.right->tn.lval;
        !           404:                p = p->in.left;
        !           405:                if( fcond( p ) ) return( gtb(p,l) );
        !           406:                if( tcond( p ) ) return( gtb(p,-1) );
        !           407:                return( condit( p, CCC, -1, l ) );
        !           408:        }
        !           409: 
        !           410:        /* a convenient place to diddle a few special ops */
        !           411:        if( callop(o) )
        !           412:        {
        !           413:                if( optype(o) == UTYPE ) p->stn.argsize = 0;
        !           414:                else p->stn.argsize = argsize(p->in.right);
        !           415:                if( goal==CEFF ) goal = NRGS;
        !           416:                /* flow on, so that we can handle if( f(...) )... */
        !           417:        }
        !           418:        else if( goal==CEFF && (asgop(o) || o==STASG || o==INIT)) goal=NRGS;
        !           419: 
        !           420:        /* do a bit of optimization */
        !           421: 
        !           422:        if( goal == NRGS ) 
        !           423:        {
        !           424:                if( logop(o) )
        !           425:                {
        !           426:                        /* must make p into ( p ? 1 : 0 ), then recompile */
        !           427:                        q1 = talloc();
        !           428:                        q1->tn.op = ICON;
        !           429:                        q1->tn.name = (char *) 0;
        !           430:                        q1->tn.lval = 1;
        !           431:                        q1->tn.type = p->tn.type;
        !           432:                        q2 = talloc();
        !           433:                        *q2 = *q1;
        !           434:                        q2->tn.lval = 0;
        !           435:                        q = talloc();
        !           436:                        q->tn.op = COLON;
        !           437:                        q->tn.type = p->tn.type;
        !           438:                        q->in.left = q1;
        !           439:                        q->in.right = q2;
        !           440:                        q1 = talloc();
        !           441:                        q1->tn.op = o = QUEST;
        !           442:                        q1->tn.type = p->tn.type;
        !           443:                        q1->in.left = p;
        !           444:                        q1->in.right = q;
        !           445:                        p = q1;  /* flow on, and compile */
        !           446:                }
        !           447:        }
        !           448: 
        !           449:        if( goal != CCC ) 
        !           450:        {
        !           451:                if( o == QUEST ) 
        !           452:                {
        !           453:                        /* rewrite ? : when goal not CCC */
        !           454:                        lf = getlab();
        !           455:                        l = getlab();
        !           456:                        p->tn.op = COMOP;
        !           457:                        q = p->in.right;
        !           458:                        q1 = condit( q->in.left, goal, -1, -1 );
        !           459:                        q->in.right = condit( q->in.right, goal, -1, -1 );
        !           460:                        if( tcond( p->in.left ) ) 
        !           461:                        {
        !           462:                                q->tn.op = FREE;
        !           463:                                tfree( q->in.right );
        !           464:                                p->in.right = q1;
        !           465:                                p->in.left=condit( p->in.left, CEFF, -1, -1 );
        !           466:                                return( rcomma( p ) );
        !           467:                        }
        !           468:                        if( fcond( p->in.left ) ) 
        !           469:                        {
        !           470:                                q->tn.op = FREE;
        !           471:                                tfree( q1 );
        !           472:                                p->in.right = q->in.right;
        !           473:                                p->in.left=condit( p->in.left, CEFF, -1, -1 );
        !           474:                                return( rcomma( p ) );
        !           475:                        }
        !           476:                        if( !q1 ) 
        !           477:                        {
        !           478:                                if( !q->in.right ) 
        !           479:                                {
        !           480:                                        /* may still have work to do
        !           481:                                        ** if left side of ? has effect
        !           482:                                        */
        !           483:                                        q1 = condit(p->in.left, goal,
        !           484:                                                -1, -1);
        !           485:                                        if (!q1)
        !           486:                                        {
        !           487:                                                tfree( p->in.left );
        !           488:                                        }
        !           489:                                        p->tn.op = q->tn.op = FREE;
        !           490:                                        return( q1 );
        !           491:                                }
        !           492:                                /* rhs done if condition is false */
        !           493:                                p->in.left = condit( p->in.left, CCC, l, -1 );
        !           494:                                p->in.right = dlabel( q->in.right, l );
        !           495:                                q->tn.op = FREE;
        !           496:                                return( p );
        !           497:                        }
        !           498:                        else if( !q->in.right ) 
        !           499:                        {
        !           500:                                /* lhs done if condition is true */
        !           501:                                p->in.left=condit( p->in.left, CCC, -1, lf );
        !           502:                                p->in.right = dlabel( q1, lf );
        !           503:                                q->tn.op = FREE;
        !           504:                                return( p );
        !           505:                        }
        !           506: 
        !           507:                        /* both sides exist and the condition is nontrivial */
        !           508:                        p->in.left = condit( p->in.left, CCC, -1, lf );
        !           509:                        q1 = force(q1);
        !           510:                        q->in.right = force(q->in.right);
        !           511:                        q1 = genbr( 0, l, q1 );
        !           512:                        q->in.left = dlabel( q1, lf );
        !           513:                        q->tn.op = COMOP;
        !           514:                        return( dlabel( p, l ) );
        !           515:                }
        !           516: 
        !           517:                if( goal == CEFF ) 
        !           518:                {
        !           519:                        /* some things may disappear */
        !           520:                        switch( o ) 
        !           521:                        {
        !           522: 
        !           523:                        case CBRANCH:
        !           524:                        case GENBR:
        !           525:                        case GENUBR:
        !           526:                        case CALL:
        !           527:                        case UNARY CALL:
        !           528:                        case FORTCALL:
        !           529:                        case UNARY FORTCALL:
        !           530:                        case STCALL:
        !           531:                        case UNARY STCALL:
        !           532:                        case STASG:
        !           533:                        case INIT:
        !           534:                        case MOD:   /* do these for the side effects */
        !           535:                        case DIV:
        !           536:                        case UOP0:
        !           537:                        case UOP1:
        !           538:                        case UOP2:
        !           539:                        case UOP3:
        !           540:                        case UOP4:
        !           541:                        case UOP5:
        !           542:                        case UOP6:
        !           543:                        case UOP7:
        !           544:                        case UOP8:
        !           545:                        case UOP9:
        !           546: #if defined(COMBINED)
        !           547:                        case GENLAB:
        !           548: #endif
        !           549:                                goal = NRGS;
        !           550:                        }
        !           551:                }
        !           552: 
        !           553:                /* The rhs of && and || ops are executed only if the
        !           554:                   result is not clear from the lhs.  If our goal is
        !           555:                   CEFF, we don't need a result, but we need to
        !           556:                   preserve that dependancy. So special case it. */
        !           557:                if (goal==CEFF)  {
        !           558:                        if (o == ANDAND) return andeff(p);
        !           559:                        if (o == OROR) return oreff(p);
        !           560:                }
        !           561:                /* This next batch of code wanders over the tree getting
        !           562:                   rid of code which is for effect only and has no
        !           563:                   effect */
        !           564:                switch( optype(o) ) 
        !           565:                {
        !           566:                case LTYPE:
        !           567:                        if( goal == CEFF ) 
        !           568:                        {
        !           569:                                p->tn.op = FREE;
        !           570:                                return( NIL );
        !           571:                        }
        !           572:                        break;
        !           573: 
        !           574:                case BITYPE:
        !           575:                        p->in.right = condit( p->in.right, goal, -1, -1 );
        !           576:                case UTYPE:
        !           577:                        p->in.left = condit( p->in.left, o==COMOP?CEFF:goal,
        !           578:                        -1, -1 );
        !           579:                }
        !           580:                /* If we are only interested in effects, we quit here */
        !           581:                if( goal == CEFF || o==COMOP ) 
        !           582:                {
        !           583:                        /* lhs or rhs may have disappeared */
        !           584:                        /* op need not get done */
        !           585: 
        !           586:                        switch( optype(o) )
        !           587:                        {
        !           588: 
        !           589:                        case BITYPE:
        !           590:                                p->tn.op = COMOP;
        !           591:                                p = rcomma(p);
        !           592:                                return ( p );
        !           593: 
        !           594:                        case UTYPE:
        !           595:                                /* don't throw out prepass's labels */
        !           596:                                if(p->in.op == GENLAB)
        !           597:                                        return(p);
        !           598:                                p->tn.op = FREE;
        !           599:                                return( p->in.left );
        !           600: 
        !           601:                        case LTYPE:
        !           602:                                p->tn.op = FREE;
        !           603:                                return( NIL );
        !           604:                        }
        !           605:                }
        !           606:                return( p );
        !           607:        }
        !           608: 
        !           609:        /* goal must = CCC from here on */
        !           610: 
        !           611:        switch( o ) 
        !           612:        {
        !           613: 
        !           614:        case ULE:
        !           615:        case ULT:
        !           616:        case UGE:
        !           617:        case UGT:
        !           618:        case EQ:
        !           619:        case NE:
        !           620:        case LE:
        !           621:        case LT:
        !           622:        case GE:
        !           623:        case GT:
        !           624:                if(t<0 ) 
        !           625:                {
        !           626:                        o = p->tn.op = negrel[o-EQ];
        !           627:                        t = f;
        !           628:                        f = -1;
        !           629:                }
        !           630: 
        !           631: #ifndef NOOPT
        !           632:                if( p->in.right->in.op == ICON &&
        !           633:                    p->in.right->tn.lval == 0 &&
        !           634:                    p->in.right->in.name == (char *) 0 ) 
        !           635:                {
        !           636:                        /* if chars are unsigned, do these optimizations
        !           637:                           as if this is an unsigned compare*/
        !           638: #ifndef CHSIGN
        !           639:                        if (
        !           640:                            ( p->in.left->tn.type == TCHAR ||
        !           641:                              ( p->in.left->in.op == CONV && 
        !           642:                                p->in.left->in.left->tn.type == TCHAR ) )
        !           643:                             && o >= LE && o <= GT)
        !           644:                                o += UGT - GT;
        !           645: #endif
        !           646: 
        !           647:                        /* the question here is whether we can assume that */
        !           648:                        /* unconditional branches preserve condition codes */
        !           649:                        /* if this turned out to be no, we would have to */
        !           650:                        /* explicitly handle this case here */
        !           651: 
        !           652:                        switch( o ) 
        !           653:                        {
        !           654: 
        !           655:                        case UGT:
        !           656:                        case ULE:
        !           657:                                o = p->in.op = (o==UGT)?NE:EQ;
        !           658:                        case EQ:
        !           659:                        case NE:
        !           660:                        case LE:
        !           661:                        case LT:
        !           662:                        case GE:
        !           663:                        case GT:
        !           664:                                if( logop( p->in.left->tn.op ) )
        !           665:                                {
        !           666:                                        /* situation like (a==0)==0 */
        !           667:                                        /* ignore optimization */
        !           668:                                        goto noopt;
        !           669:                                }
        !           670:                                break;
        !           671: 
        !           672:                        case ULT:  /* never succeeds */
        !           673:                                return( gtb( p, f ) );
        !           674: 
        !           675:                        case UGE:
        !           676:                                /* always succeeds */
        !           677:                                return( gtb( p, t ) );
        !           678:                        }
        !           679:                        p->tn.op = p->in.right->tn.op = FREE;
        !           680:                        p = condit( p->in.left, NRGS, -1, -1 );
        !           681:                        p = genbr( o, t, p );
        !           682:                        if( f<0 ) return( p );
        !           683:                        else return( genbr( 0, f, p ) );
        !           684:                }
        !           685: noopt:
        !           686: # endif
        !           687: 
        !           688:                p->in.left = condit( p->in.left, NRGS, -1, -1 );
        !           689:                p->in.right = condit( p->in.right, NRGS, -1, -1 );
        !           690:                p = genbr( o, t, p );
        !           691:                if( f>=0 ) p = genbr( 0, f, p );
        !           692:                return( p );
        !           693: 
        !           694:        case COMOP:
        !           695:                p->in.left = condit( p->in.left, CEFF, -1, -1 );
        !           696:                p->in.right = condit( p->in.right, CCC, t, f );
        !           697:                return( rcomma( p ) );
        !           698: 
        !           699:        case NOT:
        !           700:                p->tn.op = FREE;
        !           701:                return( condit( p->in.left, CCC, f, t ) );
        !           702: 
        !           703:        case ANDAND:
        !           704:                lf = f<0 ? getlab() : f;
        !           705:                lt = t<0 ? getlab() : t;
        !           706:                p->tn.op = COMOP;
        !           707:                if( tcond( p->in.left ) )
        !           708:                {
        !           709:                        /* left is always true */
        !           710:                        p->in.left = condit( p->in.left, CEFF, -1, -1 );
        !           711:                        p->in.right = condit( p->in.right, CCC, t, f );
        !           712:                }
        !           713:                else  {
        !           714:                        /* lhs not always true */
        !           715:                        if( tcond( p->in.right ) )
        !           716:                        {
        !           717:                                /* rhs is always true */
        !           718:                                p->in.right =
        !           719:                                   condit( p->in.right, CEFF, -1, -1 );
        !           720:                                if (p->in.right)  {
        !           721:                                    /* const with sideeffect */
        !           722:                                    p->in.left = 
        !           723:                                        condit( p->in.left, CCC, -1,lf);
        !           724:                                    p->in.right = condit( p->in.right,
        !           725:                                        CCC, t, t );
        !           726:                                } else
        !           727:                                    p->in.left =
        !           728:                                     condit( p->in.left, CCC, t, f );
        !           729:                        } else  {
        !           730:                                p->in.left =
        !           731:                                     condit( p->in.left, CCC, -1, lf );
        !           732:                                p->in.right =
        !           733:                                   condit( p->in.right, CCC, t, f );
        !           734:                        }
        !           735:                }
        !           736:                q = rcomma( p );
        !           737:                if( f<0 ) q = dlabel( q, lf );
        !           738:                if( t<0 ) q = dlabel( q, lt );
        !           739:                return( q );
        !           740: 
        !           741:        case OROR:
        !           742:                lf = f<0 ? getlab() : f;
        !           743:                lt = t<0 ? getlab() : t;
        !           744:                p->tn.op = COMOP;
        !           745:                if( fcond( p->in.left ) )
        !           746:                {
        !           747:                        /* left is always false */
        !           748:                        p->in.left = condit( p->in.left, CEFF, -1, -1 );
        !           749:                        p->in.right = condit( p->in.right, CCC, t, f );
        !           750:                }
        !           751:                else  {
        !           752:                        /* left is not always false */
        !           753:                        if( fcond( p->in.right ) )
        !           754:                        {
        !           755:                                /* right always false */
        !           756:                                p->in.right =
        !           757:                                   condit( p->in.right, CEFF, -1, -1 );
        !           758:                                if (p->in.right) {  
        !           759:                                    /* const with sideeffect */
        !           760:                                    p->in.left = 
        !           761:                                        condit( p->in.left, CCC, lt,-1);
        !           762:                                    /* This may generate a superfluous
        !           763:                                       test.  Tough. */
        !           764:                                    p->in.right = condit( p->in.right,
        !           765:                                        CCC, f, f );
        !           766:                                } else
        !           767:                                    p->in.left =
        !           768:                                     condit( p->in.left, CCC, t, f );
        !           769:                        } else  {
        !           770:                                p->in.left =
        !           771:                                     condit( p->in.left, CCC, lt, -1 );
        !           772:                                p->in.right =
        !           773:                                   condit( p->in.right, CCC, t, f );
        !           774:                        }
        !           775:                }
        !           776:                p = rcomma( p );
        !           777:                if( f<0 ) p = dlabel( p, lf );
        !           778:                if( t<0 ) p = dlabel( p, lt );
        !           779:                return( p );
        !           780: 
        !           781:        case QUEST:
        !           782:                lf = f<0 ? getlab() : f;
        !           783:                lt = t<0 ? getlab() : t;
        !           784:                p->in.left = condit( p->in.left, CCC, -1, l=getlab() );
        !           785:                q = p->in.right;
        !           786:                q1 = condit( q->in.left, goal, lt, lf );
        !           787:                q->in.left = dlabel( q1, l );
        !           788:                q->in.right = condit( q->in.right, goal, t, f );
        !           789:                p->tn.op = COMOP;
        !           790:                q->tn.op = COMOP;
        !           791:                if( t<0 ) p = dlabel( p, lt );
        !           792:                if( f<0 ) p = dlabel( p, lf );
        !           793:                return( p );
        !           794: 
        !           795:        default:
        !           796:                /* get the condition codes, generate the branch */
        !           797:                switch( optype(o) )
        !           798:                {
        !           799:                case BITYPE:
        !           800:                        p->in.right = condit( p->in.right, NRGS, -1, -1 );
        !           801:                case UTYPE:
        !           802:                        p->in.left = condit( p->in.left, NRGS, -1, -1 );
        !           803:                }
        !           804:                if( t>=0 ) p = genbr( NE, t, p );
        !           805:                if( f>=0 ) p = genbr( (t>=0)?0:EQ, f, p );
        !           806:                return( p );
        !           807:        }
        !           808: }
        !           809: 
        !           810: # ifndef TWOPASS
        !           811: 
        !           812: p2compile( p )
        !           813: register NODE *p; 
        !           814: {
        !           815:        if( lflag ) lineid(p->ln.lineno ? p->ln.lineno : lineno, ftitle );
        !           816:        tmpoff = 0;  /* expression at top level reuses temps */
        !           817:        /* generate code for the tree p */
        !           818: 
        !           819: # ifdef MYREADER
        !           820:        MYREADER(p);  /* do your own laundering of the input */
        !           821: # endif
        !           822:        /* eliminate the conditionals */
        !           823: # ifndef NODBG
        !           824:        if( p && odebug>2 ) e2print(p);
        !           825: # endif
        !           826:        /*p = prepass(p);*/
        !           827:        if(p)
        !           828:                p = condit( p, CEFF, -1, -1 );
        !           829:        if( p ) 
        !           830:        {
        !           831:                /* expression does something */
        !           832:                /* generate the code */
        !           833: # ifndef NODBG
        !           834:                if( odebug>2 ) e2print(p);
        !           835: # endif
        !           836:                pjwreader(p);
        !           837:                pjwend(p);
        !           838:        }
        !           839: # ifndef NODBG
        !           840:        else if( odebug>1 ) printf( "null effect\n" );
        !           841: # endif
        !           842:        allchk();
        !           843:        /* tcheck will be done by the first pass at the end of a ftn. */
        !           844:        /* first pass will do it... */
        !           845: }
        !           846: 
        !           847: p2bbeg( aoff, myreg ) 
        !           848: register aoff,myreg;
        !           849: {
        !           850:        static int myftn = -1;
        !           851:        SETOFF( aoff, ALSTACK );
        !           852:        if( myftn != ftnno )
        !           853:        {
        !           854:                 /* beginning of function */
        !           855:                maxboff = aoff;
        !           856:                myftn = ftnno;
        !           857:                maxtemp = 0;
        !           858:                maxarg = 0;
        !           859:        }
        !           860:        else 
        !           861:        {
        !           862:                if( aoff > maxboff ) maxboff = aoff;
        !           863:        }
        !           864: # ifdef SETREGS
        !           865:        SETREGS(myreg);
        !           866: # endif
        !           867: }
        !           868: 
        !           869: p2bend()
        !           870: {
        !           871:        SETOFF( maxboff, ALSTACK );
        !           872:        SETOFF( maxarg, ALSTACK );
        !           873:        SETOFF( maxtemp, ALSTACK );
        !           874:        eobl2();
        !           875:        maxboff = maxarg = maxtemp = 0;
        !           876: }
        !           877: 
        !           878: # endif

unix.superglobalmegacorp.com

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