Annotation of researchv9/jerq/sgs/comp/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();
                     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: p2init( argc, argv )
                     47: char *argv[];
                     48: {
                     49:        /* set the values of the pass 2 arguments */
                     50: 
                     51:        register int c;
                     52:        register char *cp;
                     53:        register files;
                     54: 
                     55:        allo0();  /* free all regs */
                     56:        files = 0;
                     57: 
                     58:        for( c=1; c<argc; ++c )
                     59:        {
                     60:                if( *(cp=argv[c]) == '-' )
                     61:                {
                     62:                        while( *++cp )
                     63:                        {
                     64:                                switch( *cp )
                     65:                                {
                     66: 
                     67:                                case 'X':  /* pass1 flags */
                     68:                                        while( *++cp ) 
                     69:                                        {
                     70:                                                 /* VOID */ 
                     71:                                        }
                     72:                                        --cp;
                     73:                                        break;
                     74: 
                     75:                                case 'l':  /* linenos */
                     76:                                        ++lflag;
                     77:                                        break;
                     78: 
                     79:                                case 'e':  /* expressions */
                     80:                                        ++e2debug;
                     81:                                        break;
                     82: 
                     83:                                case 'o':  /* orders */
                     84:                                        ++odebug;
                     85:                                        break;
                     86: 
                     87:                                case 'r':  /* register allocation */
                     88:                                        ++rdebug;
                     89:                                        break;
                     90: 
                     91:                                case 's':  /* shapes */
                     92:                                        ++sdebug;
                     93:                                        break;
                     94: 
                     95:                                case 'u':  /* Sethi-Ullman testing
                     96:                                                (machine dependent) */
                     97:                                        ++udebug;
                     98:                                        break;
                     99: 
                    100:                                case 'f':  /* try for faster compile speed */
                    101:                                        ++fast;
                    102:                                        break;
                    103: 
                    104:                                default:
                    105:                                        cerror( "bad option: %c", *cp );
                    106:                                }
                    107:                        }
                    108:                }
                    109:                else files = 1;  /* assumed to be a ftitle */
                    110:        }
                    111: 
                    112:        mkdope();
                    113:        return( files );
                    114: }
                    115: 
                    116: NODE *
                    117: dlabel( p, l )
                    118: register NODE *p; 
                    119: {
                    120:        /* define a label after p is executed */
                    121:        register NODE *q;
                    122:        if( !p ) cerror( "dlabel" );
                    123:        q = talloc();
                    124:        q->tn.type = p->tn.type;
                    125:        q->in.left = p;
                    126:        q->tn.op = GENLAB;
                    127:        q->bn.label = l;
                    128:        return( q );
                    129: }
                    130: 
                    131: 
                    132: NODE *
                    133: genbr( o, l, p )
                    134: register NODE *p; 
                    135: register o,l;
                    136: {
                    137:        /* after evaluating p, generate a branch to l */
                    138:        /* if o is 0, unconditional */
                    139:        register NODE *q;
                    140:        if( !p ) cerror( "genbr" );
                    141:        if( l < 0 ) cerror( "genbr1" );
                    142:        q = talloc();
                    143:        q->tn.op = o?GENBR:GENUBR;
                    144:        q->tn.type = p->tn.type;
                    145:        q->in.left = p;
                    146:        q->bn.label = l;
                    147:        q->bn.lop = o;
                    148:        if( o && logop(p->tn.op) &&
                    149:                (p->tn.op != ANDAND) 
                    150:                && (p->tn.op != OROR)
                    151:        ) p->tn.op = CMP;
                    152:        return( q );
                    153: }
                    154: 
                    155: 
                    156: static NODE *
                    157: oreff(p)
                    158: register NODE *p;
                    159: {
                    160:        register NODE *r, *l;
                    161:        NODE *condit(), *seq();
                    162:        int lab, t, f;
                    163:        /* oreff is called if an || op is evaluated with goal=CEFF
                    164:           The rhs of || ops should be executed only if the
                    165:           lhs is false.  Since our goal is CEFF, we don't need
                    166:           a result of the ||, but we need to
                    167:           preserve that dependancy with this special case */
                    168: 
                    169:        /* We must catch this case before its children are
                    170:           condit() and change the goal on it left child to CCC */
                    171:           
                    172:        if (tcond(p->in.left))  {
                    173:                tfree(p->in.right);
                    174:                p->in.op = FREE;
                    175:                p = condit( p->in.left, CEFF, -1, -1);
                    176:        } else if (fcond(p->in.left))  {
                    177:                p->in.op = COMOP;
                    178:                p = condit( p, CEFF, -1, -1);
                    179:        } else {
                    180:                lab = getlab();
                    181:                l = condit( p->in.left, CCC, lab, -1);
                    182:                r = condit( p->in.right, CEFF, -1, -1);
                    183:                p->in.op = FREE;
                    184:                p = seq(l, r);  /* put r after l */
                    185:                p = dlabel(p, lab);
                    186:        }
                    187:        return p;
                    188: }
                    189: static NODE *
                    190: andeff(p)
                    191: register NODE *p;
                    192: {
                    193:        register NODE *r, *l;
                    194:        NODE *condit();
                    195:        int lab, t, f;
                    196:        /* andeff is called if an && op is evaluated with goal=CEFF
                    197:           The rhs of && ops should be executed only if the
                    198:           lhs is true.  Since our goal is CEFF, we don't need
                    199:           a result of the &&, but we need to
                    200:           preserve that dependancy with this special case */
                    201: 
                    202:        /* We must catch this case before its children are
                    203:           condit() and change the goal on it left child to CCC */
                    204:           
                    205:        if (fcond(p->in.left))  {
                    206:                tfree(p->in.right);
                    207:                p->in.op = FREE;
                    208:                p = condit( p->in.left, CEFF, -1, -1);
                    209:        } else if (tcond(p->in.left))  {
                    210:                p->in.op = COMOP;
                    211:                p = condit( p, CEFF, -1, -1);
                    212:        } else {
                    213:                lab = getlab();
                    214:                p->in.op = FREE;
                    215:                l = condit( p->in.left, CCC, -1, lab);
                    216:                r = condit( p->in.right, CEFF, -1, -1);
                    217:                p = seq(l, r);  /* put r after l */
                    218:                p = dlabel(p, lab);
                    219:        }
                    220:        return p;
                    221: }
                    222: int negrel[] = 
                    223: {
                    224:         NE, EQ, GT, GE, LT, LE, UGT, UGE, ULT, ULE 
                    225: } ;  /* negatives of relationals */
                    226: 
                    227: tcond( p )
                    228: register NODE *p; 
                    229: {
                    230:        /* return 1 if p is always true, 0 otherwise */
                    231:        register o = p->tn.op;
                    232:        register NODE *q;
                    233: 
                    234:        switch( o ) 
                    235:        {
                    236: 
                    237:        case ICON:
                    238:                return( p->tn.lval || p->tn.name != (char *) 0 );
                    239: 
                    240:        case COMOP:
                    241:                return( tcond( p->in.right ) );
                    242: 
                    243:        case ANDAND:
                    244:                return( tcond( p->in.left ) && tcond( p->in.right ) );
                    245: 
                    246:        case OROR:
                    247:                return( tcond( p->in.left ) || tcond( p->in.right ) );
                    248: 
                    249:        case NOT:
                    250:                return( fcond( p->in.left ) );
                    251: 
                    252:        case QUEST:
                    253:                q = p->in.right;
                    254:                if( tcond( p->in.left ) ) return( tcond( q->in.left ) );
                    255:                if( fcond( p->in.left ) ) return( tcond( q->in.right ) );
                    256:                return( tcond( q->in.left ) && tcond( q->in.right ) );
                    257: 
                    258:        default:
                    259:                return( 0 );
                    260:        }
                    261: }
                    262: 
                    263: fcond( p )
                    264: register NODE *p; 
                    265: {
                    266:        /* return 1 if p is always false, 0 otherwise */
                    267:        register o = p->tn.op;
                    268:        register NODE *q;
                    269: 
                    270:        switch( o ) 
                    271:        {
                    272: 
                    273:        case ICON:
                    274:                return( !p->tn.lval && p->tn.name == (char *) 0 );
                    275: 
                    276:        case COMOP:
                    277:                return( fcond( p->in.right ) );
                    278: 
                    279:        case ANDAND:
                    280:                return( fcond( p->in.left ) || fcond( p->in.right ) );
                    281: 
                    282:        case OROR:
                    283:                return( fcond( p->in.left ) && fcond( p->in.right ) );
                    284: 
                    285:        case NOT:
                    286:                return( tcond( p->in.left ) );
                    287: 
                    288:        case QUEST:
                    289:                q = p->in.right;
                    290:                if( tcond( p->in.left ) ) return( fcond( q->in.left ) );
                    291:                if( fcond( p->in.left ) ) return( fcond( q->in.right ) );
                    292:                return( fcond( q->in.left ) && fcond( q->in.right ) );
                    293: 
                    294:        default:
                    295:                return( 0 );
                    296:        }
                    297: }
                    298: 
                    299: NODE *
                    300: rcomma( p )
                    301: register NODE *p; 
                    302: {
                    303:        /* p is a COMOP; return the shrunken version thereof */
                    304: 
                    305:        if( p->tn.op != COMOP ) cerror( "rcomma" );
                    306: 
                    307:        if( p->in.left && p->in.right ) return( p );
                    308:        p->tn.op = FREE;
                    309:        if( !p->in.left ) return( p->in.right );
                    310:        return( p->in.left );
                    311: }
                    312: 
                    313: NODE *
                    314: seq( p1, p2 )
                    315: register NODE *p1, *p2;
                    316: {
                    317:        /* execute p then q */
                    318:        register NODE *q;
                    319: 
                    320:        q = talloc();
                    321:        if (!p1) return p2;
                    322:        if (!p2) return p1;
                    323:        q->in.op = COMOP;
                    324:        q->in.type = p2->in.right->in.type;
                    325:        q->in.left = p1;
                    326:        q->in.right = p2;
                    327:        return q;
                    328: }
                    329: 
                    330: NODE *
                    331: gtb( p, l )
                    332: register NODE *p; 
                    333: register l;
                    334: {
                    335:        register NODE *q;
                    336:        /* replace p by a trivial branch to l */
                    337:        /* if l is -1, return NULL */
                    338:        q = condit( p, CEFF, -1, -1 );
                    339:        if( l<0 ) return( q );
                    340:        if( !q ) 
                    341:        {
                    342:                q = talloc();
                    343:                q->tn.op = ICON;
                    344:                q->tn.lval = 0;
                    345:                q->tn.name = (char *) 0;
                    346:                q->tn.type = TINT;
                    347:        }
                    348:        return( genbr( 0, l, q ) );
                    349: }
                    350: 
                    351: NODE *
                    352: condit( p, goal, t, f )
                    353: register NODE *p; 
                    354: register goal,t,f;
                    355: {
                    356:        /* generate code for conditionals in terms of GENLAB and GENBR nodes */
                    357:        /* goal is either CEFF, NRGS, or CCC */
                    358:        /* also, delete stuff that never needs get done */
                    359:        /* if goal==CEFF, return of null means nothing to be done */
                    360: 
                    361:        register o, lt, lf, l;
                    362:        register NODE *q, *q1, *q2;
                    363: 
                    364:        o = p->tn.op;
                    365: 
                    366: #ifndef NODBG
                    367:        if( odebug >2 ) 
                    368:        {
                    369:                printf( "condit( %d (%s), %s, %d, %d )\n", (int)(p-node),
                    370:                opst[o], goal==CCC?"CCC":(goal==NRGS?"NRGS":"CEFF"),
                    371:                t, f );
                    372:        }
                    373: #endif
                    374:        if( o == CBRANCH ) 
                    375:        {
                    376:                p->in.right->tn.op = p->tn.op = FREE;
                    377:                l = p->in.right->tn.lval;
                    378:                p = p->in.left;
                    379:                if( fcond( p ) ) return( gtb(p,l) );
                    380:                if( tcond( p ) ) return( gtb(p,-1) );
                    381:                return( condit( p, CCC, -1, l ) );
                    382:        }
                    383: 
                    384:        /* a convenient place to diddle a few special ops */
                    385:        if( callop(o) )
                    386:        {
                    387:                if( optype(o) == UTYPE ) p->stn.argsize = 0;
                    388:                else p->stn.argsize = argsize(p->in.right);
                    389:                if( goal==CEFF ) goal = NRGS;
                    390:                /* flow on, so that we can handle if( f(...) )... */
                    391:        }
                    392:        else if( goal==CEFF && (asgop(o) || o==STASG || o==INIT)) goal=NRGS;
                    393: 
                    394:        /* do a bit of optimization */
                    395: 
                    396:        if( goal == NRGS ) 
                    397:        {
                    398:                if( logop(o) )
                    399:                {
                    400:                        /* must make p into ( p ? 1 : 0 ), then recompile */
                    401:                        q1 = talloc();
                    402:                        q1->tn.op = ICON;
                    403:                        q1->tn.name = (char *) 0;
                    404:                        q1->tn.lval = 1;
                    405:                        q1->tn.type = p->tn.type;
                    406:                        q2 = talloc();
                    407:                        *q2 = *q1;
                    408:                        q2->tn.lval = 0;
                    409:                        q = talloc();
                    410:                        q->tn.op = COLON;
                    411:                        q->tn.type = p->tn.type;
                    412:                        q->in.left = q1;
                    413:                        q->in.right = q2;
                    414:                        q1 = talloc();
                    415:                        q1->tn.op = o = QUEST;
                    416:                        q1->tn.type = p->tn.type;
                    417:                        q1->in.left = p;
                    418:                        q1->in.right = q;
                    419:                        p = q1;  /* flow on, and compile */
                    420:                }
                    421:        }
                    422: 
                    423:        if( goal != CCC ) 
                    424:        {
                    425:                if( o == QUEST ) 
                    426:                {
                    427:                        /* rewrite ? : when goal not CCC */
                    428:                        lf = getlab();
                    429:                        l = getlab();
                    430:                        p->tn.op = COMOP;
                    431:                        q = p->in.right;
                    432:                        q1 = condit( q->in.left, goal, -1, -1 );
                    433:                        q->in.right = condit( q->in.right, goal, -1, -1 );
                    434:                        if( tcond( p->in.left ) ) 
                    435:                        {
                    436:                                q->tn.op = FREE;
                    437:                                tfree( q->in.right );
                    438:                                p->in.right = q1;
                    439:                                p->in.left=condit( p->in.left, CEFF, -1, -1 );
                    440:                                return( rcomma( p ) );
                    441:                        }
                    442:                        if( fcond( p->in.left ) ) 
                    443:                        {
                    444:                                q->tn.op = FREE;
                    445:                                tfree( q1 );
                    446:                                p->in.right = q->in.right;
                    447:                                p->in.left=condit( p->in.left, CEFF, -1, -1 );
                    448:                                return( rcomma( p ) );
                    449:                        }
                    450:                        if( !q1 ) 
                    451:                        {
                    452:                                if( !q->in.right ) 
                    453:                                {
                    454:                                        /* may still have work to do
                    455:                                        ** if left side of ? has effect
                    456:                                        */
                    457:                                        q1 = condit(p->in.left, goal,
                    458:                                                -1, -1);
                    459:                                        if (!q1)
                    460:                                        {
                    461:                                                tfree( p->in.left );
                    462:                                        }
                    463:                                        p->tn.op = q->tn.op = FREE;
                    464:                                        return( q1 );
                    465:                                }
                    466:                                /* rhs done if condition is false */
                    467:                                p->in.left = condit( p->in.left, CCC, l, -1 );
                    468:                                p->in.right = dlabel( q->in.right, l );
                    469:                                q->tn.op = FREE;
                    470:                                return( p );
                    471:                        }
                    472:                        else if( !q->in.right ) 
                    473:                        {
                    474:                                /* lhs done if condition is true */
                    475:                                p->in.left=condit( p->in.left, CCC, -1, lf );
                    476:                                p->in.right = dlabel( q1, lf );
                    477:                                q->tn.op = FREE;
                    478:                                return( p );
                    479:                        }
                    480: 
                    481:                        /* both sides exist and the condition is nontrivial */
                    482:                        p->in.left = condit( p->in.left, CCC, -1, lf );
                    483:                        q1 = force(q1);
                    484:                        q->in.right = force(q->in.right);
                    485:                        q1 = genbr( 0, l, q1 );
                    486:                        q->in.left = dlabel( q1, lf );
                    487:                        q->tn.op = COMOP;
                    488:                        return( dlabel( p, l ) );
                    489:                }
                    490: 
                    491:                if( goal == CEFF ) 
                    492:                {
                    493:                        /* some things may disappear */
                    494:                        switch( o ) 
                    495:                        {
                    496: 
                    497:                        case CBRANCH:
                    498:                        case GENBR:
                    499:                        case GENUBR:
                    500:                        case CALL:
                    501:                        case UNARY CALL:
                    502:                        case FORTCALL:
                    503:                        case UNARY FORTCALL:
                    504:                        case STCALL:
                    505:                        case UNARY STCALL:
                    506:                        case STASG:
                    507:                        case INIT:
                    508:                        case MOD:   /* do these for the side effects */
                    509:                        case DIV:
                    510:                        case UOP0:
                    511:                        case UOP1:
                    512:                        case UOP2:
                    513:                        case UOP3:
                    514:                        case UOP4:
                    515:                        case UOP5:
                    516:                        case UOP6:
                    517:                        case UOP7:
                    518:                        case UOP8:
                    519:                        case UOP9:
                    520:                                goal = NRGS;
                    521:                        }
                    522:                }
                    523: 
                    524:                /* The rhs of && and || ops are executed only if the
                    525:                   result is not clear from the lhs.  If our goal is
                    526:                   CEFF, we don't need a result, but we need to
                    527:                   preserve that dependancy. So special case it. */
                    528:                if (goal==CEFF)  {
                    529:                        if (o == ANDAND) return andeff(p);
                    530:                        if (o == OROR) return oreff(p);
                    531:                }
                    532:                /* This next batch of code wanders over the tree getting
                    533:                   rid of code which is for effect only and has no
                    534:                   effect */
                    535:                switch( optype(o) ) 
                    536:                {
                    537:                case LTYPE:
                    538:                        if( goal == CEFF ) 
                    539:                        {
                    540:                                p->tn.op = FREE;
                    541:                                return( NIL );
                    542:                        }
                    543:                        break;
                    544: 
                    545:                case BITYPE:
                    546:                        p->in.right = condit( p->in.right, goal, -1, -1 );
                    547:                case UTYPE:
                    548:                        p->in.left = condit( p->in.left, o==COMOP?CEFF:goal,
                    549:                        -1, -1 );
                    550:                }
                    551:                /* If we are only interested in effects, we quit here */
                    552:                if( goal == CEFF || o==COMOP ) 
                    553:                {
                    554:                        /* lhs or rhs may have disappeared */
                    555:                        /* op need not get done */
                    556: 
                    557:                        switch( optype(o) )
                    558:                        {
                    559: 
                    560:                        case BITYPE:
                    561:                                p->tn.op = COMOP;
                    562:                                p = rcomma(p);
                    563:                                return ( p );
                    564: 
                    565:                        case UTYPE:
                    566:                                p->tn.op = FREE;
                    567:                                return( p->in.left );
                    568: 
                    569:                        case LTYPE:
                    570:                                p->tn.op = FREE;
                    571:                                return( NIL );
                    572:                        }
                    573:                }
                    574:                return( p );
                    575:        }
                    576: 
                    577:        /* goal must = CCC from here on */
                    578: 
                    579:        switch( o ) 
                    580:        {
                    581: 
                    582:        case ULE:
                    583:        case ULT:
                    584:        case UGE:
                    585:        case UGT:
                    586:        case EQ:
                    587:        case NE:
                    588:        case LE:
                    589:        case LT:
                    590:        case GE:
                    591:        case GT:
                    592:                if(t<0 ) 
                    593:                {
                    594:                        o = p->tn.op = negrel[o-EQ];
                    595:                        t = f;
                    596:                        f = -1;
                    597:                }
                    598: 
                    599: #ifndef NOOPT
                    600:                if( p->in.right->in.op == ICON &&
                    601:                    p->in.right->tn.lval == 0 &&
                    602:                    p->in.right->in.name == (char *) 0 ) 
                    603:                {
                    604:                        /* if chars are unsigned, do these optimizations
                    605:                           as if this is an unsigned compare*/
                    606: #ifndef CHSIGN
                    607:                        if (
                    608:                            ( p->in.left->tn.type == TCHAR ||
                    609:                              ( p->in.left->in.op == CONV && 
                    610:                                p->in.left->in.left->tn.type == TCHAR ) )
                    611:                             && o >= LE && o <= GT)
                    612:                                o += UGT - GT;
                    613: #endif
                    614: 
                    615:                        /* the question here is whether we can assume that */
                    616:                        /* unconditional branches preserve condition codes */
                    617:                        /* if this turned out to be no, we would have to */
                    618:                        /* explicitly handle this case here */
                    619: 
                    620:                        switch( o ) 
                    621:                        {
                    622: 
                    623:                        case UGT:
                    624:                        case ULE:
                    625:                                o = p->in.op = (o==UGT)?NE:EQ;
                    626:                        case EQ:
                    627:                        case NE:
                    628:                        case LE:
                    629:                        case LT:
                    630:                        case GE:
                    631:                        case GT:
                    632:                                if( logop( p->in.left->tn.op ) )
                    633:                                {
                    634:                                        /* situation like (a==0)==0 */
                    635:                                        /* ignore optimization */
                    636:                                        goto noopt;
                    637:                                }
                    638:                                break;
                    639: 
                    640:                        case ULT:  /* never succeeds */
                    641:                                return( gtb( p, f ) );
                    642: 
                    643:                        case UGE:
                    644:                                /* always succeeds */
                    645:                                return( gtb( p, t ) );
                    646:                        }
                    647:                        p->tn.op = p->in.right->tn.op = FREE;
                    648:                        p = condit( p->in.left, NRGS, -1, -1 );
                    649:                        p = genbr( o, t, p );
                    650:                        if( f<0 ) return( p );
                    651:                        else return( genbr( 0, f, p ) );
                    652:                }
                    653: noopt:
                    654: # endif
                    655: 
                    656:                p->in.left = condit( p->in.left, NRGS, -1, -1 );
                    657:                p->in.right = condit( p->in.right, NRGS, -1, -1 );
                    658:                p = genbr( o, t, p );
                    659:                if( f>=0 ) p = genbr( 0, f, p );
                    660:                return( p );
                    661: 
                    662:        case COMOP:
                    663:                p->in.left = condit( p->in.left, CEFF, -1, -1 );
                    664:                p->in.right = condit( p->in.right, CCC, t, f );
                    665:                return( rcomma( p ) );
                    666: 
                    667:        case NOT:
                    668:                p->tn.op = FREE;
                    669:                return( condit( p->in.left, CCC, f, t ) );
                    670: 
                    671:        case ANDAND:
                    672:                lf = f<0 ? getlab() : f;
                    673:                lt = t<0 ? getlab() : t;
                    674:                p->tn.op = COMOP;
                    675:                if( tcond( p->in.left ) )
                    676:                {
                    677:                        /* left is always true */
                    678:                        p->in.left = condit( p->in.left, CEFF, -1, -1 );
                    679:                        p->in.right = condit( p->in.right, CCC, t, f );
                    680:                }
                    681:                else  {
                    682:                        /* lhs not always true */
                    683:                        if( tcond( p->in.right ) )
                    684:                        {
                    685:                                /* rhs is always true */
                    686:                                p->in.right =
                    687:                                   condit( p->in.right, CEFF, -1, -1 );
                    688:                                if (p->in.right)  {
                    689:                                    /* const with sideeffect */
                    690:                                    p->in.left = 
                    691:                                        condit( p->in.left, CCC, -1,lf);
                    692:                                    p->in.right = condit( p->in.right,
                    693:                                        CCC, t, t );
                    694:                                } else
                    695:                                    p->in.left =
                    696:                                     condit( p->in.left, CCC, t, f );
                    697:                        } else  {
                    698:                                p->in.left =
                    699:                                     condit( p->in.left, CCC, -1, lf );
                    700:                                p->in.right =
                    701:                                   condit( p->in.right, CCC, t, f );
                    702:                        }
                    703:                }
                    704:                q = rcomma( p );
                    705:                if( f<0 ) q = dlabel( q, lf );
                    706:                if( t<0 ) q = dlabel( q, lt );
                    707:                return( q );
                    708: 
                    709:        case OROR:
                    710:                lf = f<0 ? getlab() : f;
                    711:                lt = t<0 ? getlab() : t;
                    712:                p->tn.op = COMOP;
                    713:                if( fcond( p->in.left ) )
                    714:                {
                    715:                        /* left is always false */
                    716:                        p->in.left = condit( p->in.left, CEFF, -1, -1 );
                    717:                        p->in.right = condit( p->in.right, CCC, t, f );
                    718:                }
                    719:                else  {
                    720:                        /* left is not always false */
                    721:                        if( fcond( p->in.right ) )
                    722:                        {
                    723:                                /* right always false */
                    724:                                p->in.right =
                    725:                                   condit( p->in.right, CEFF, -1, -1 );
                    726:                                if (p->in.right) {  
                    727:                                    /* const with sideeffect */
                    728:                                    p->in.left = 
                    729:                                        condit( p->in.left, CCC, lt,-1);
                    730:                                    /* This may generate a superfluous
                    731:                                       test.  Tough. */
                    732:                                    p->in.right = condit( p->in.right,
                    733:                                        CCC, f, f );
                    734:                                } else
                    735:                                    p->in.left =
                    736:                                     condit( p->in.left, CCC, t, f );
                    737:                        } else  {
                    738:                                p->in.left =
                    739:                                     condit( p->in.left, CCC, lt, -1 );
                    740:                                p->in.right =
                    741:                                   condit( p->in.right, CCC, t, f );
                    742:                        }
                    743:                }
                    744:                p = rcomma( p );
                    745:                if( f<0 ) p = dlabel( p, lf );
                    746:                if( t<0 ) p = dlabel( p, lt );
                    747:                return( p );
                    748: 
                    749:        case QUEST:
                    750:                lf = f<0 ? getlab() : f;
                    751:                lt = t<0 ? getlab() : t;
                    752:                p->in.left = condit( p->in.left, CCC, -1, l=getlab() );
                    753:                q = p->in.right;
                    754:                q1 = condit( q->in.left, goal, lt, lf );
                    755:                q->in.left = dlabel( q1, l );
                    756:                q->in.right = condit( q->in.right, goal, t, f );
                    757:                p->tn.op = COMOP;
                    758:                q->tn.op = COMOP;
                    759:                if( t<0 ) p = dlabel( p, lt );
                    760:                if( f<0 ) p = dlabel( p, lf );
                    761:                return( p );
                    762: 
                    763:        default:
                    764:                /* get the condition codes, generate the branch */
                    765:                switch( optype(o) )
                    766:                {
                    767:                case BITYPE:
                    768:                        p->in.right = condit( p->in.right, NRGS, -1, -1 );
                    769:                case UTYPE:
                    770:                        p->in.left = condit( p->in.left, NRGS, -1, -1 );
                    771:                }
                    772:                if( t>=0 ) p = genbr( NE, t, p );
                    773:                if( f>=0 ) p = genbr( (t>=0)?0:EQ, f, p );
                    774:                return( p );
                    775:        }
                    776: }
                    777: 
                    778: # ifndef TWOPASS
                    779: 
                    780: p2compile( p )
                    781: register NODE *p; 
                    782: {
                    783:        if( lflag ) lineid( lineno, ftitle );
                    784:        tmpoff = 0;  /* expression at top level reuses temps */
                    785:        /* generate code for the tree p */
                    786: 
                    787: # ifdef MYREADER
                    788:        MYREADER(p);  /* do your own laundering of the input */
                    789: # endif
                    790:        /* eliminate the conditionals */
                    791: # ifndef NODBG
                    792:        if( p && odebug>2 ) e2print(p);
                    793: # endif
                    794:        p = condit( p, CEFF, -1, -1 );
                    795:        if( p ) 
                    796:        {
                    797:                /* expression does something */
                    798:                /* generate the code */
                    799: # ifndef NODBG
                    800:                if( odebug>2 ) e2print(p);
                    801: # endif
                    802:                codgen( p );
                    803:        }
                    804: # ifndef NODBG
                    805:        else if( odebug>1 ) printf( "null effect\n" );
                    806: # endif
                    807:        allchk();
                    808:        /* tcheck will be done by the first pass at the end of a ftn. */
                    809:        /* first pass will do it... */
                    810: }
                    811: 
                    812: p2bbeg( aoff, myreg ) 
                    813: register aoff,myreg;
                    814: {
                    815:        static int myftn = -1;
                    816:        SETOFF( aoff, ALSTACK );
                    817:        if( myftn != ftnno )
                    818:        {
                    819:                 /* beginning of function */
                    820:                maxboff = aoff;
                    821:                myftn = ftnno;
                    822:                maxtemp = 0;
                    823:                maxarg = 0;
                    824:        }
                    825:        else 
                    826:        {
                    827:                if( aoff > maxboff ) maxboff = aoff;
                    828:        }
                    829: # ifdef SETREGS
                    830:        SETREGS(myreg);
                    831: # endif
                    832: }
                    833: 
                    834: p2bend()
                    835: {
                    836:        SETOFF( maxboff, ALSTACK );
                    837:        SETOFF( maxarg, ALSTACK );
                    838:        SETOFF( maxtemp, ALSTACK );
                    839:        eobl2();
                    840:        maxboff = maxarg = maxtemp = 0;
                    841: }
                    842: 
                    843: # endif
                    844: 
                    845: char *cnames[] = 
                    846: {
                    847:        "CEFF",
                    848:        "NRGS",
                    849:        "CCC",
                    850:        0,
                    851: };
                    852: 
                    853: prgoal( goal ) 
                    854: register goal;
                    855: {
                    856:        /* print a nice-looking description of goal */
                    857: 
                    858:        register i, flag;
                    859: 
                    860:        flag = 0;
                    861:        for( i=0; cnames[i]; ++i )
                    862:        {
                    863:                if( goal & (1<<i) )
                    864:                {
                    865:                        if( flag ) printf( "|" );
                    866:                        ++flag;
                    867:                        printf( cnames[i] );
                    868:                }
                    869:        }
                    870:        if( !flag ) printf( "?%o", goal );
                    871: 
                    872: }
                    873: 
                    874: #ifndef NODBG
                    875: e2print( p )
                    876: register NODE *p; 
                    877: {
                    878:        printf( "\n********* costs=(0,...,NRGS;EFF;TEMP;CC)\n" );
                    879:        e22print( p ,"T");
                    880:        printf("=========\n");
                    881: }
                    882: 
                    883: e22print( p ,s)
                    884: register NODE *p; 
                    885: char *s;
                    886: {
                    887:        static down=0;
                    888:        register ty;
                    889: 
                    890:        ty = optype( p->tn.op );
                    891:        if( ty == BITYPE )
                    892:        {
                    893:                ++down;
                    894:                e22print( p->in.right ,"R");
                    895:                --down;
                    896:        }
                    897:        e222print( down, p, s );
                    898: 
                    899:        if( ty != LTYPE )
                    900:        {
                    901:                ++down;
                    902:                e22print( p->in.left, "L" );
                    903:                --down;
                    904:        }
                    905: }
                    906: 
                    907: e222print( down, p, s )
                    908: NODE *p; 
                    909: char *s;
                    910: {
                    911:        /* print one node */
                    912:        int i, d;
                    913: 
                    914:        for( d=down; d>1; d -= 2 ) printf( "\t" );
                    915:        if( d ) printf( "    " );
                    916: 
                    917:        printf( "%s.%d) op= '%s'",s, (int)(p-node), opst[p->in.op] );
                    918:        switch( p->in.op ) 
                    919:        {
                    920:                 /* special cases */
                    921:        case REG:
                    922:                printf( " %s", rnames[p->tn.rval] );
                    923:                break;
                    924: 
                    925:        case ICON:
                    926:        case NAME:
                    927:        case VAUTO:
                    928:        case VPARAM:
                    929:        case TEMP:
                    930:                printf( " " );
                    931:                adrput( p );
                    932:                break;
                    933: 
                    934:        case STCALL:
                    935:        case UNARY STCALL:
                    936:                printf( " args=%d", p->stn.argsize );
                    937:        case STARG:
                    938:        case STASG:
                    939:                printf( " size=%d", p->stn.stsize );
                    940:                printf( " align=%d", p->stn.stalign );
                    941:                break;
                    942: 
                    943:        case GENBR:
                    944:                printf( " %d (%s)", p->bn.label, opst[p->bn.lop] );
                    945:                break;
                    946: 
                    947:        case CALL:
                    948:        case UNARY CALL:
                    949:                printf( " args=%d", p->stn.argsize );
                    950:                break;
                    951: 
                    952:        case GENUBR:
                    953:        case GENLAB:
                    954:                printf( " %d", p->bn.label );
                    955:                break;
                    956: 
                    957:        case FUNARG:
                    958:                printf( " offset=%d", p->tn.rval );
                    959: 
                    960:        }
                    961: 
                    962:        printf( ", " );
                    963:        t2print( p->in.type );
                    964:        printf( ", c=[" );
                    965:        for( i=0; i<NRGS; ++i ) cprt( p->in.cst[i], "," );
                    966:        cprt( p->in.cst[NRGS], "; " );
                    967:        cprt( p->in.cst[CEFF], "; " );
                    968:        cprt( p->in.cst[CTEMP], "; " );
                    969:        cprt( p->in.cst[CCC], "]" );
                    970:        if( p->tn.goal == CEFF ) printf( " (EFF)\n" );
                    971:        else if( p->tn.goal == CCC ) printf( " (CC)\n" );
                    972:        else if( p->tn.goal != NRGS ) printf( "(BAD GOAL: %d)\n", p->tn.goal );
                    973:        else printf( "\n" );
                    974: }
                    975: 
                    976: t2print( t )
                    977: TWORD t;
                    978: {
                    979:        int i;
                    980:        static struct {
                    981:                TWORD mask;
                    982:                char * string;
                    983:                } t2tab[] = {
                    984:                        TANY, "ANY",
                    985:                        TINT, "INT",
                    986:                        TUNSIGNED, "UNSIGNED",
                    987:                        TCHAR, "CHAR",
                    988:                        TUCHAR, "UCHAR",
                    989:                        TSHORT, "SHORT",
                    990:                        TUSHORT, "USHORT",
                    991:                        TLONG, "LONG",
                    992:                        TULONG, "ULONG",
                    993:                        TFLOAT, "FLOAT",
                    994:                        TDOUBLE, "DOUBLE",
                    995:                        TPOINT, "POINTER",
                    996:                        TPOINT2, "POINTER2",
                    997:                        TSTRUCT, "STRUCT",
                    998:                        TVOID, "VOID",
                    999:                        0, 0
                   1000:                        };
                   1001: 
                   1002:        for( i=0; t && t2tab[i].mask; ++i ) {
                   1003:                if( (t&t2tab[i].mask) == t2tab[i].mask ) {
                   1004:                        printf( " %s", t2tab[i].string );
                   1005:                        t ^= t2tab[i].mask;
                   1006:                        }
                   1007:                }
                   1008:        }
                   1009: 
                   1010: # else
                   1011: e2print( p )
                   1012: NODE *p; 
                   1013: {
                   1014:        werror( "e2print not compiled" );
                   1015: }
                   1016: e222print( p, s )
                   1017: NODE *p; 
                   1018: char *s;
                   1019: {
                   1020:        werror( "e222print not compiled" );
                   1021: }
                   1022: # endif
                   1023: cprt( c, s )
                   1024: register char *s; 
                   1025: register c;
                   1026: {
                   1027:        if( c >= INFINITY ) printf( "*%s", s );
                   1028:        else printf( "%d%s", c, s );
                   1029: }

unix.superglobalmegacorp.com

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