Annotation of researchv10no/cmd/ccom/common/reader.c, revision 1.1.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.