Annotation of researchv9/jerq/sgs/comp/reader.c, revision 1.1

1.1     ! root        1: /*     @(#) reader.c : 1.7 3/5/84      */
        !             2: 
        !             3: # include "mfile2.h"
        !             4: 
        !             5: /*     some storage declarations */
        !             6: 
        !             7: # ifdef TWOPASS
        !             8: NODE node[TREESZ];
        !             9: char ftitle[100] = "\"\"";  /* the name of the file */
        !            10: int ftnno;  /* number of current function */
        !            11: int lineno;
        !            12: #endif
        !            13: 
        !            14: int lflag;
        !            15: int e2debug;
        !            16: int udebug;
        !            17: int fast;
        !            18: 
        !            19: /* maxtemp is the maximum size (in bits) needed for temps so far */
        !            20: /* maxarg is ditto for outgoing arguments */
        !            21: /* maxboff is ditto for automatic variables */
        !            22: /* earlier attempts to keep these on a per-block basis were silly */
        !            23: int maxtemp;
        !            24: extern int maxarg;
        !            25: int maxboff;
        !            26: NODE * condit();
        !            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.