Annotation of 43BSDTahoe/lib/old_compiler/pcc/pcc.tahoe/local2.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char sccsid[] = "@(#)local2.c   1.11 (Berkeley) 6/4/87";
                      3: #endif
                      4: 
                      5: # include "pass2.h"
                      6: # include <ctype.h>
                      7: 
                      8: # define putstr(s)     fputs((s), stdout)
                      9: # define ISCHAR(p)     (p->in.type == UCHAR || p->in.type == CHAR)
                     10: 
                     11: # ifdef FORT
                     12: int ftlab1, ftlab2;
                     13: # endif
                     14: /* a lot of the machine dependent parts of the second pass */
                     15: 
                     16: # define BITMASK(n) ((1L<<n)-1)
                     17: 
                     18: # ifndef ONEPASS
                     19: where(c){
                     20:        fprintf( stderr, "%s, line %d: ", filename, lineno );
                     21:        }
                     22: # endif
                     23: 
                     24: lineid( l, fn ) char *fn; {
                     25:        /* identify line l and file fn */
                     26:        printf( "#      line %d, file %s\n", l, fn );
                     27:        }
                     28: 
                     29: int ent_mask;
                     30: 
                     31: eobl2(){
                     32:        register OFFSZ spoff;   /* offset from stack pointer */
                     33: #ifndef FORT
                     34:        extern int ftlab1, ftlab2;
                     35: #endif
                     36: 
                     37:        spoff = maxoff;
                     38:        spoff /= SZCHAR;
                     39:        SETOFF(spoff,4);
                     40: #ifdef FORT
                     41: #ifndef FLEXNAMES
                     42:        printf( "       .set    .F%d,%d\n", ftnno, spoff );
                     43: #else
                     44:        /* SHOULD BE L%d ... ftnno but must change pc/f77 */
                     45:        printf( "       .set    LF%d,%d\n", ftnno, spoff );
                     46: #endif
                     47:        printf( "       .set    LWM%d,0x%x\n", ftnno, ent_mask&0x1ffc|0x1000);
                     48: #else
                     49:        printf( "       .set    L%d,0x%x\n", ftnno, ent_mask&0x1ffc);
                     50:        printf( "L%d:\n", ftlab1);
                     51:        if( maxoff > AUTOINIT )
                     52:                printf( "       subl3   $%d,fp,sp\n", spoff);
                     53:        printf( "       jbr     L%d\n", ftlab2);
                     54: #endif
                     55:        ent_mask = 0;
                     56:        maxargs = -1;
                     57:        }
                     58: 
                     59: struct hoptab { int opmask; char * opstring; } ioptab[] = {
                     60: 
                     61:        PLUS,   "add",
                     62:        MINUS,  "sub",
                     63:        MUL,    "mul",
                     64:        DIV,    "div",
                     65:        MOD,    "div",
                     66:        OR,     "or",
                     67:        ER,     "xor",
                     68:        AND,    "and",
                     69:        -1,     ""    };
                     70: 
                     71: hopcode( f, o ){
                     72:        /* output the appropriate string from the above table */
                     73: 
                     74:        register struct hoptab *q;
                     75: 
                     76:        if(asgop(o))
                     77:                o = NOASG o;
                     78:        for( q = ioptab;  q->opmask>=0; ++q ){
                     79:                if( q->opmask == o ){
                     80:                        if(f == 'E')
                     81:                                printf( "e%s", q->opstring);
                     82:                        else
                     83:                                printf( "%s%c", q->opstring, tolower(f));
                     84:                        return;
                     85:                        }
                     86:                }
                     87:        cerror( "no hoptab for %s", opst[o] );
                     88:        }
                     89: 
                     90: char *
                     91: rnames[] = {  /* keyed to register number tokens */
                     92: 
                     93:        "r0", "r1",
                     94:        "r2", "r3", "r4", "r5",
                     95:        "r6", "r7", "r8", "r9", "r10", "r11",
                     96:        "r12", "fp", "sp", "pc",
                     97:        };
                     98: 
                     99: /* output register name and update entry mask */
                    100: char *
                    101: rname(r)
                    102:        register int r;
                    103: {
                    104: 
                    105:        ent_mask |= 1<<r;
                    106:        return(rnames[r]);
                    107: }
                    108: 
                    109: int rstatus[] = {
                    110:        SAREG|STAREG, SAREG|STAREG,
                    111:        SAREG|STAREG, SAREG|STAREG, SAREG|STAREG, SAREG|STAREG,
                    112:        SAREG, SAREG, SAREG, SAREG, SAREG, SAREG,
                    113:        SAREG, SAREG, SAREG, SAREG,
                    114:        };
                    115: 
                    116: tlen(p) NODE *p;
                    117: {
                    118:        switch(p->in.type) {
                    119:                case CHAR:
                    120:                case UCHAR:
                    121:                        return(1);
                    122: 
                    123:                case SHORT:
                    124:                case USHORT:
                    125:                        return(2);
                    126: 
                    127:                case DOUBLE:
                    128:                        return(8);
                    129: 
                    130:                default:
                    131:                        return(4);
                    132:                }
                    133: }
                    134: 
                    135: anyfloat(p, q)
                    136:        NODE *p, *q;
                    137: {
                    138:        register TWORD tp, tq;
                    139: 
                    140:        tp = p->in.type;
                    141:        tq = q->in.type;
                    142:        return (tp == FLOAT || tp == DOUBLE || tq == FLOAT || tq == DOUBLE);
                    143: }
                    144: 
                    145: prtype(n) NODE *n;
                    146: {
                    147:        switch (n->in.type)
                    148:                {
                    149: 
                    150:                case DOUBLE:
                    151:                        putchar('d');
                    152:                        return;
                    153: 
                    154:                case FLOAT:
                    155:                        putchar('f');
                    156:                        return;
                    157: 
                    158:                case INT:
                    159:                case UNSIGNED:
                    160:                        putchar('l');
                    161:                        return;
                    162: 
                    163:                case SHORT:
                    164:                case USHORT:
                    165:                        putchar('w');
                    166:                        return;
                    167: 
                    168:                case CHAR:
                    169:                case UCHAR:
                    170:                        putchar('b');
                    171:                        return;
                    172: 
                    173:                default:
                    174:                        if ( !ISPTR( n->in.type ) ) cerror("zzzcode- bad type");
                    175:                        else {
                    176:                                putchar('l');
                    177:                                return;
                    178:                                }
                    179:                }
                    180: }
                    181: 
                    182: zzzcode( p, c ) register NODE *p; {
                    183:        register int m;
                    184:        int val;
                    185:        switch( c ){
                    186: 
                    187:        case 'N':  /* logical ops, turned into 0-1 */
                    188:                /* use register given by register 1 */
                    189:                cbgen( 0, m=getlab(), 'I' );
                    190:                deflab( p->bn.label );
                    191:                printf( "       clrl    %s\n", rname(getlr( p, '1' )->tn.rval) );
                    192:                deflab( m );
                    193:                return;
                    194: 
                    195:        case 'P':
                    196:                cbgen( p->in.op, p->bn.label, c );
                    197:                return;
                    198: 
                    199:        case 'A':       /* assignment and load (integer only) */
                    200:                {
                    201:                register NODE *l, *r;
                    202: 
                    203:                if (xdebug) eprint(p, 0, &val, &val);
                    204:                r = getlr(p, 'R');
                    205:                if (optype(p->in.op) == LTYPE || p->in.op == UNARY MUL) {
                    206:                        l = resc;
                    207:                        l->in.type = INT;
                    208:                } else
                    209:                        l = getlr(p, 'L');
                    210:                if(r->in.type==FLOAT || r->in.type==DOUBLE
                    211:                 || l->in.type==FLOAT || l->in.type==DOUBLE)
                    212:                        cerror("float in ZA");
                    213:                if (r->in.op == ICON)
                    214:                        if(r->in.name[0] == '\0') {
                    215:                                if (r->tn.lval == 0) {
                    216:                                        putstr("clr");
                    217:                                        prtype(l);
                    218:                                        putchar('\t');
                    219:                                        adrput(l);
                    220:                                        return;
                    221:                                }
                    222:                                if (r->tn.lval < 0 && r->tn.lval >= -63) {
                    223:                                        putstr("mneg");
                    224:                                        prtype(l);
                    225:                                        r->tn.lval = -r->tn.lval;
                    226:                                        goto ops;
                    227:                                }
                    228: #ifdef MOVAFASTER
                    229:                        } else {
                    230:                                putstr("movab\t");
                    231:                                acon(r);
                    232:                                putchar(',');
                    233:                                adrput(l);
                    234:                                return;
                    235: #endif MOVAFASTER
                    236:                        }
                    237: 
                    238:                if (l->in.op == REG) {
                    239:                        if( tlen(l) < tlen(r) ) {
                    240:                                putstr(!ISUNSIGNED(l->in.type)?
                    241:                                        "cvt": "movz");
                    242:                                prtype(l);
                    243:                                putchar('l');
                    244:                                goto ops;
                    245:                        } else
                    246:                                l->in.type = INT;
                    247:                }
                    248:                if (tlen(l) == tlen(r)) {
                    249:                        putstr("mov");
                    250:                        prtype(l);
                    251:                        goto ops;
                    252:                } else if (tlen(l) > tlen(r) && ISUNSIGNED(r->in.type))
                    253:                        putstr("movz");
                    254:                else
                    255:                        putstr("cvt");
                    256:                prtype(r);
                    257:                prtype(l);
                    258:        ops:
                    259:                putchar('\t');
                    260:                adrput(r);
                    261:                putchar(',');
                    262:                adrput(l);
                    263:                return;
                    264:                }
                    265: 
                    266:        case 'B':       /* get oreg value in temp register for shift */
                    267:                {
                    268:                register NODE *r;
                    269:                if (xdebug) eprint(p, 0, &val, &val);
                    270:                r = p->in.right;
                    271:                if( tlen(r) == sizeof(int) && r->in.type != FLOAT )
                    272:                        putstr("movl");
                    273:                else {
                    274:                        putstr(ISUNSIGNED(r->in.type) ? "movz" : "cvt");
                    275:                        prtype(r);
                    276:                        putchar('l');
                    277:                        }
                    278:                return;
                    279:                }
                    280: 
                    281:        case 'C':       /* num bytes pushed on arg stack */
                    282:                {
                    283:                extern int gc_numbytes;
                    284:                extern int xdebug;
                    285: 
                    286:                if (xdebug) printf("->%d<-",gc_numbytes);
                    287: 
                    288:                printf("call%c  $%d",
                    289:                 (p->in.left->in.op==ICON && gc_numbytes<60)?'f':'s',
                    290:                 gc_numbytes+4);
                    291:                /* dont change to double (here's the only place to catch it) */
                    292:                if(p->in.type == FLOAT)
                    293:                        rtyflg = 1;
                    294:                return;
                    295:                }
                    296: 
                    297:        case 'D':       /* INCR and DECR */
                    298:                zzzcode(p->in.left, 'A');
                    299:                putstr("\n      ");
                    300: 
                    301:        case 'E':       /* INCR and DECR, FOREFF */
                    302:                if (p->in.right->tn.lval == 1)
                    303:                        {
                    304:                        putstr(p->in.op == INCR ? "inc" : "dec");
                    305:                        prtype(p->in.left);
                    306:                        putchar('\t');
                    307:                        adrput(p->in.left);
                    308:                        return;
                    309:                        }
                    310:                putstr(p->in.op == INCR ? "add" : "sub");
                    311:                prtype(p->in.left);
                    312:                putstr("2       ");
                    313:                adrput(p->in.right);
                    314:                putchar(',');
                    315:                adrput(p->in.left);
                    316:                return;
                    317: 
                    318:        case 'F':       /* masked constant for fields */
                    319:                printf(ACONFMT, (p->in.right->tn.lval&((1<<fldsz)-1))<<fldshf);
                    320:                return;
                    321: 
                    322:        case 'H':       /* opcode for shift */
                    323:                if(p->in.op == LS || p->in.op == ASG LS)
                    324:                        putstr("shll");
                    325:                else if(ISUNSIGNED(p->in.left->in.type))
                    326:                        putstr("shrl");
                    327:                else
                    328:                        putstr("shar");
                    329:                return;
                    330: 
                    331:        case 'L':       /* type of left operand */
                    332:        case 'R':       /* type of right operand */
                    333:                {
                    334:                register NODE *n;
                    335:                extern int xdebug;
                    336: 
                    337:                n = getlr ( p, c);
                    338:                if (xdebug) printf("->%d<-", n->in.type);
                    339: 
                    340:                prtype(n);
                    341:                return;
                    342:                }
                    343: 
                    344:        case 'M': {  /* initiate ediv for mod and unsigned div */
                    345:                register char *r;
                    346:                m = getlr(p, '1')->tn.rval;
                    347:                r = rname(m);
                    348:                printf("\tclrl\t%s\n\tmovl\t", r);
                    349:                adrput(p->in.left);
                    350:                printf(",%s\n", rname(m+1));
                    351:                if(!ISUNSIGNED(p->in.type)) {   /* should be MOD */
                    352:                        m = getlab();
                    353:                        printf("\tjgeq\tL%d\n\tmnegl\t$1,%s\n", m, r);
                    354:                        deflab(m);
                    355:                }
                    356:                return;
                    357:        }
                    358: 
                    359:        case 'T': {     /* rounded structure length for arguments */
                    360:                int size = p->stn.stsize;
                    361:                SETOFF( size, 4);
                    362:                printf("movab   -%d(sp),sp", size);
                    363:                return;
                    364:        }
                    365: 
                    366:        case 'S':  /* structure assignment */
                    367:                stasg(p);
                    368:                break;
                    369: 
                    370:        case 'X':       /* multiplication for short and char */
                    371:                if (ISUNSIGNED(p->in.left->in.type)) 
                    372:                        printf("\tmovz");
                    373:                else
                    374:                        printf("\tcvt");
                    375:                zzzcode(p, 'L');
                    376:                printf("l\t");
                    377:                adrput(p->in.left);
                    378:                printf(",");
                    379:                adrput(&resc[0]);
                    380:                printf("\n");
                    381:                if (ISUNSIGNED(p->in.right->in.type)) 
                    382:                        printf("\tmovz");
                    383:                else
                    384:                        printf("\tcvt");
                    385:                zzzcode(p, 'R');
                    386:                printf("l\t");
                    387:                adrput(p->in.right);
                    388:                printf(",");
                    389:                adrput(&resc[1]);
                    390:                printf("\n");
                    391:                return;
                    392: 
                    393:        case 'U':               /* SCONV */
                    394:        case 'V':               /* SCONV with FORCC */
                    395:                sconv(p, c == 'V');
                    396:                break;
                    397: 
                    398:        case 'Z':
                    399:                p = p->in.right;
                    400:                switch (p->in.type) {
                    401:                case SHORT: {
                    402:                        short w = p->tn.lval;
                    403:                        p->tn.lval = w;
                    404:                        break;
                    405:                }
                    406:                case CHAR: {
                    407:                        char c = p->tn.lval;
                    408:                        p->tn.lval = c;
                    409:                        break;
                    410:                }
                    411:                }
                    412:                printf("$%d", p->tn.lval);
                    413:                break;
                    414: 
                    415:        default:
                    416:                cerror( "illegal zzzcode" );
                    417:        }
                    418: }
                    419: 
                    420: #define        MOVB(dst, src, off) { \
                    421:        putstr("\tmovb\t"); upput(src, off); putchar(','); \
                    422:        upput(dst, off); putchar('\n'); \
                    423: }
                    424: #define        MOVW(dst, src, off) { \
                    425:        putstr("\tmovw\t"); upput(src, off); putchar(','); \
                    426:        upput(dst, off); putchar('\n'); \
                    427: }
                    428: #define        MOVL(dst, src, off) { \
                    429:        putstr("\tmovl\t"); upput(src, off); putchar(','); \
                    430:        upput(dst, off); putchar('\n'); \
                    431: }
                    432: /*
                    433:  * Generate code for a structure assignment.
                    434:  */
                    435: stasg(p)
                    436:        register NODE *p;
                    437: {
                    438:        register NODE *l, *r;
                    439:        register int size;
                    440: 
                    441:        switch (p->in.op) {
                    442:        case STASG:                     /* regular assignment */
                    443:                l = p->in.left;
                    444:                r = p->in.right;
                    445:                break;
                    446:        case STARG:                     /* place arg on the stack */
                    447:                l = getlr(p, '3');
                    448:                r = p->in.left;
                    449:                break;
                    450:        default:
                    451:                cerror("STASG bad");
                    452:                /*NOTREACHED*/
                    453:        }
                    454:        /*
                    455:         * Pun source for use in code generation.
                    456:         */
                    457:        switch (r->in.op) {
                    458:        case ICON:
                    459:                r->in.op = NAME;
                    460:                break;
                    461:        case REG:
                    462:                r->in.op = OREG;
                    463:                break;
                    464:        default:
                    465:                cerror( "STASG-r" );
                    466:                /*NOTREACHED*/
                    467:        }
                    468:        size = p->stn.stsize;
                    469:        if (size <= 0 || size > 65535)
                    470:                cerror("structure size out of range");
                    471:        /*
                    472:         * Generate optimized code based on structure size
                    473:         * and alignment properties....
                    474:         */
                    475:        switch (size) {
                    476: 
                    477:        case 1:
                    478:                putstr("\tmovb\t");
                    479:        optimized:
                    480:                adrput(r);
                    481:                putchar(',');
                    482:                adrput(l);
                    483:                putchar('\n');
                    484:                break;
                    485: 
                    486:        case 2:
                    487:                if (p->stn.stalign != 2) {
                    488:                        MOVB(l, r, SZCHAR);
                    489:                        putstr("\tmovb\t");
                    490:                } else
                    491:                        putstr("\tmovw\t");
                    492:                goto optimized;
                    493: 
                    494:        case 4:
                    495:                if (p->stn.stalign != 4) {
                    496:                        if (p->stn.stalign != 2) {
                    497:                                MOVB(l, r, 3*SZCHAR);
                    498:                                MOVB(l, r, 2*SZCHAR);
                    499:                                MOVB(l, r, 1*SZCHAR);
                    500:                                putstr("\tmovb\t");
                    501:                        } else {
                    502:                                MOVW(l, r, SZSHORT);
                    503:                                putstr("\tmovw\t");
                    504:                        }
                    505:                } else
                    506:                        putstr("\tmovl\t");
                    507:                goto optimized;
                    508: 
                    509:        case 6:
                    510:                if (p->stn.stalign != 2)
                    511:                        goto movblk;
                    512:                MOVW(l, r, 2*SZSHORT);
                    513:                MOVW(l, r, 1*SZSHORT);
                    514:                putstr("\tmovw\t");
                    515:                goto optimized;
                    516: 
                    517:        case 8:
                    518:                if (p->stn.stalign == 4) {
                    519:                        MOVL(l, r, SZLONG);
                    520:                        putstr("\tmovl\t");
                    521:                        goto optimized;
                    522:                }
                    523:                /* fall thru...*/
                    524: 
                    525:        default:
                    526:        movblk:
                    527:                /*
                    528:                 * Can we ever get a register conflict with R1 here?
                    529:                 */
                    530:                putstr("\tmovab\t");
                    531:                if(r->in.op == OREG && r->tn.rval == R1)
                    532:                {
                    533:                        adrput(r);
                    534:                        printf(",r0\n\tmovab\t");
                    535:                        adrput(l);
                    536:                        putstr(",r1\n");
                    537:                }
                    538:                else
                    539:                {
                    540:                        adrput(l);
                    541:                        putstr(",r1\n\tmovab\t");
                    542:                        adrput(r);
                    543:                        printf(",r0\n");
                    544:                }
                    545:                printf("\tmovl\t$%d,r2\n\tmovblk\n", size);
                    546:                rname(R2);
                    547:                break;
                    548:        }
                    549:        /*
                    550:         * Reverse above pun for reclaim.
                    551:         */
                    552:        if (r->in.op == NAME)
                    553:                r->in.op = ICON;
                    554:        else if (r->in.op == OREG)
                    555:                r->in.op = REG;
                    556: }
                    557: 
                    558: /*
                    559:  * Output the address of the second item in the
                    560:  * pair pointed to by p.
                    561:  */
                    562: upput(p, size)
                    563:        register NODE *p;
                    564: {
                    565:        CONSZ save;
                    566: 
                    567:        if (p->in.op == FLD)
                    568:                p = p->in.left;
                    569:        switch (p->in.op) {
                    570: 
                    571:        case NAME:
                    572:        case OREG:
                    573:                save = p->tn.lval;
                    574:                p->tn.lval += size/SZCHAR;
                    575:                adrput(p);
                    576:                p->tn.lval = save;
                    577:                break;
                    578: 
                    579:        case REG:
                    580:                if (size == SZLONG) {
                    581:                        putstr(rname(p->tn.rval+1));
                    582:                        break;
                    583:                }
                    584:                /* fall thru... */
                    585: 
                    586:        default:
                    587:                cerror("illegal upper address op %s size %d",
                    588:                    opst[p->tn.op], size);
                    589:                /*NOTREACHED*/
                    590:        }
                    591: }
                    592: 
                    593: /*
                    594:  * Generate code for storage conversions.
                    595:  */
                    596: sconv(p, forcc)
                    597:        NODE *p;
                    598: {
                    599:        register NODE *l, *r;
                    600:        register wfrom, wto;
                    601:        int oltype;
                    602: 
                    603:        l = getlr(p, '1');
                    604:        oltype = l->in.type, l->in.type = r->in.type;
                    605:        r = getlr(p, 'L');
                    606:        wfrom = tlen(r), wto = tlen(l);
                    607:        if (wfrom == wto)               /* e.g. int -> unsigned */
                    608:                goto done;
                    609:        /*
                    610:         * Conversion in registers requires care
                    611:         * as cvt and movz instruction don't work
                    612:         * as expected (they end up as plain mov's).
                    613:         */
                    614:        if (l->in.op == REG && r->in.op == REG) {
                    615:                if ((wfrom < wto && ISUNSIGNED(r->in.type)) ||
                    616:                    (wto < wfrom && ISUNSIGNED(l->in.type))) {
                    617:                        /* unsigned, mask */
                    618:                        if (r->tn.rval != l->tn.rval) {
                    619:                                printf("\tandl3\t$%d,", (1<<(wto*SZCHAR))-1);
                    620:                                adrput(r);
                    621:                                putchar(',');
                    622:                        } else
                    623:                                printf("\tandl2\t$%d,", (1<<(wto*SZCHAR))-1);
                    624:                        adrput(l);
                    625:                } else {                                /* effect sign-extend */
                    626:                        printf("\tpushl\t"); adrput(r);
                    627:                        printf("\n\tcvt"); prtype(l);
                    628:                        printf("l\t%d(sp),", sizeof (int) - wto); adrput(l);
                    629:                        printf("\n\tmovab\t4(sp),sp");
                    630:                }
                    631:                /*
                    632:                 * If condition codes are required then we must generate a
                    633:                 * test of the appropriate type.
                    634:                 */
                    635:                if (forcc) {
                    636:                        printf("\n\tcmp");
                    637:                        prtype(l);
                    638:                        putchar('\t');
                    639:                        adrput(l);
                    640:                        printf(",$0");
                    641:                }
                    642:        } else {
                    643:                /*
                    644:                 * Conversion with at least one parameter in memory.
                    645:                 */
                    646:                if (wfrom < wto) {              /* expanding datum */
                    647:                        if (ISUNSIGNED(r->in.type)) {
                    648:                                printf("\tmovz");
                    649:                                prtype(r);
                    650:                                /*
                    651:                                 * If target is a register, generate
                    652:                                 * movz?l so optimizer can compress
                    653:                                 * argument pushes.
                    654:                                 */
                    655:                                if (l->in.op == REG)
                    656:                                        putchar('l');
                    657:                                else
                    658:                                        prtype(l);
                    659:                        } else {
                    660:                                printf("\tcvt");
                    661:                                prtype(r), prtype(l);
                    662:                        }
                    663:                        putchar('\t');
                    664:                        adrput(r);
                    665:                } else {                        /* shrinking dataum */
                    666:                        int off = wfrom - wto;
                    667:                        if (l->in.op == REG) {
                    668:                                printf("\tmovz");
                    669:                                prtype(l);
                    670:                                putchar('l');
                    671:                        } else {
                    672:                                printf("\tcvt");
                    673:                                prtype(l), prtype(r);
                    674:                        }
                    675:                        putchar('\t');
                    676:                        switch (r->in.op) {
                    677:                        case NAME: case OREG:
                    678:                                r->tn.lval += off;
                    679:                                adrput(r);
                    680:                                r->tn.lval -= off;
                    681:                                break;
                    682:                        case REG: case ICON: case UNARY MUL:
                    683:                                adrput(r);
                    684:                                break;
                    685:                        default:
                    686:                                cerror("sconv: bad shrink op");
                    687:                                /*NOTREACHED*/
                    688:                        }
                    689:                }
                    690:                putchar(',');
                    691:                adrput(l);
                    692:        }
                    693:        putchar('\n');
                    694: done:
                    695:        l->in.type = oltype;
                    696: }
                    697: 
                    698: rmove( rt, rs, t ) TWORD t;{
                    699:        printf( "       movl    %s,%s\n", rname(rs), rname(rt) );
                    700:        if(t==DOUBLE)
                    701:                printf( "       movl    %s,%s\n", rname(rs+1), rname(rt+1) );
                    702:        }
                    703: 
                    704: struct respref
                    705: respref[] = {
                    706:        INTAREG|INTBREG,        INTAREG|INTBREG,
                    707:        INAREG|INBREG,  INAREG|INBREG|SOREG|STARREG|STARNM|SNAME|SCON,
                    708:        INTEMP, INTEMP,
                    709:        FORARG, FORARG,
                    710:        INTEMP, INTAREG|INAREG|INTBREG|INBREG|SOREG|STARREG|STARNM,
                    711:        0,      0 };
                    712: 
                    713: setregs(){ /* set up temporary registers */
                    714:        fregs = 6;      /* tbl- 6 free regs on Tahoe (0-5) */
                    715:        }
                    716: 
                    717: #ifndef szty
                    718: szty(t) TWORD t;{ /* size, in registers, needed to hold thing of type t */
                    719:        return(t==DOUBLE ? 2 : 1 );
                    720:        }
                    721: #endif
                    722: 
                    723: rewfld( p ) NODE *p; {
                    724:        return(1);
                    725:        }
                    726: 
                    727: callreg(p) NODE *p; {
                    728:        return( R0 );
                    729:        }
                    730: 
                    731: base( p ) register NODE *p; {
                    732:        register int o = p->in.op;
                    733: 
                    734:        if( (o==ICON && p->in.name[0] != '\0')) return( 100 ); /* ie no base reg */
                    735:        if( o==REG ) return( p->tn.rval );
                    736:     if( (o==PLUS || o==MINUS) && p->in.left->in.op == REG && p->in.right->in.op==ICON)
                    737:                return( p->in.left->tn.rval );
                    738:     if( o==OREG && !R2TEST(p->tn.rval) && (p->in.type==INT || p->in.type==UNSIGNED || ISPTR(p->in.type)) )
                    739:                return( p->tn.rval + 0200*1 );
                    740:        return( -1 );
                    741:        }
                    742: 
                    743: offset( p, tyl ) register NODE *p; int tyl; {
                    744: 
                    745:        if(tyl > 8) return( -1 );
                    746:        if( tyl==1 && p->in.op==REG && (p->in.type==INT || p->in.type==UNSIGNED) ) return( p->tn.rval );
                    747:        if( (p->in.op==LS && p->in.left->in.op==REG && (p->in.left->in.type==INT || p->in.left->in.type==UNSIGNED) &&
                    748:              (p->in.right->in.op==ICON && p->in.right->in.name[0]=='\0')
                    749:              && (1<<p->in.right->tn.lval)==tyl))
                    750:                return( p->in.left->tn.rval );
                    751:        return( -1 );
                    752:        }
                    753: 
                    754: makeor2( p, q, b, o) register NODE *p, *q; register int b, o; {
                    755:        register NODE *t;
                    756:        register int i;
                    757:        NODE *f;
                    758: 
                    759:        p->in.op = OREG;
                    760:        f = p->in.left;         /* have to free this subtree later */
                    761: 
                    762:        /* init base */
                    763:        switch (q->in.op) {
                    764:                case ICON:
                    765:                case REG:
                    766:                case OREG:
                    767:                        t = q;
                    768:                        break;
                    769: 
                    770:                case MINUS:
                    771:                        q->in.right->tn.lval = -q->in.right->tn.lval;
                    772:                case PLUS:
                    773:                        t = q->in.right;
                    774:                        break;
                    775: 
                    776:                case UNARY MUL:
                    777:                        t = q->in.left->in.left;
                    778:                        break;
                    779: 
                    780:                default:
                    781:                        cerror("illegal makeor2");
                    782:        }
                    783: 
                    784:        p->tn.lval = t->tn.lval;
                    785: #ifndef FLEXNAMES
                    786:        for(i=0; i<NCHNAM; ++i)
                    787:                p->in.name[i] = t->in.name[i];
                    788: #else
                    789:        p->in.name = t->in.name;
                    790: #endif
                    791: 
                    792:        /* init offset */
                    793:        p->tn.rval = R2PACK( (b & 0177), o, (b>>7) );
                    794: 
                    795:        tfree(f);
                    796:        return;
                    797:        }
                    798: 
                    799: canaddr( p ) NODE *p; {
                    800:        register int o = p->in.op;
                    801: 
                    802:        if( o==NAME || o==REG || o==ICON || o==OREG || (o==UNARY MUL && shumul(p->in.left)) ) return(1);
                    803:        return(0);
                    804:        }
                    805: 
                    806: #ifndef shltype
                    807: shltype( o, p ) register NODE *p; {
                    808:        return( o== REG || o == NAME || o == ICON || o == OREG || ( o==UNARY MUL && shumul(p->in.left)) );
                    809:        }
                    810: #endif
                    811: 
                    812: flshape( p ) NODE *p; {
                    813:        register int o = p->in.op;
                    814: 
                    815:        if( o==NAME || o==REG || o==ICON || o==OREG || (o==UNARY MUL && shumul(p->in.left)) ) return(1);
                    816:        return(0);
                    817:        }
                    818: 
                    819: shtemp( p ) register NODE *p; {
                    820:        if( p->in.op == STARG ) p = p->in.left;
                    821:        return( p->in.op==NAME || p->in.op ==ICON || p->in.op == OREG || (p->in.op==UNARY MUL && shumul(p->in.left)) );
                    822:        }
                    823: 
                    824: shumul( p ) register NODE *p; {
                    825:        register int o;
                    826:        extern int xdebug;
                    827: 
                    828:        if (xdebug) {
                    829:                 printf("\nshumul:op=%d,lop=%d,rop=%d", p->in.op, p->in.left->in.op, p->in.right->in.op);
                    830:                printf(" prname=%s,plty=%d, prlval=%D\n", p->in.right->in.name, p->in.left->in.type, p->in.right->tn.lval);
                    831:                }
                    832: 
                    833:        o = p->in.op;
                    834:        if(( o == NAME || (o == OREG && !R2TEST(p->tn.rval)) || o == ICON )
                    835:         && p->in.type != PTR+DOUBLE)
                    836:                return( STARNM );
                    837: 
                    838:        return( 0 );
                    839:        }
                    840: 
                    841: special( p, shape ) register NODE *p; {
                    842:        if( shape==SIREG && p->in.op == OREG && R2TEST(p->tn.rval) ) return(1);
                    843:        else return(0);
                    844: }
                    845: 
                    846: adrcon( val ) CONSZ val; {
                    847:        printf(ACONFMT, val);
                    848:        }
                    849: 
                    850: conput( p ) register NODE *p; {
                    851:        switch( p->in.op ){
                    852: 
                    853:        case ICON:
                    854:                acon( p );
                    855:                return;
                    856: 
                    857:        case REG:
                    858:                putstr(rname(p->tn.rval));
                    859:                return;
                    860: 
                    861:        default:
                    862:                cerror( "illegal conput" );
                    863:                }
                    864:        }
                    865: 
                    866: insput( p ) NODE *p; {
                    867:        cerror( "insput" );
                    868:        }
                    869: 
                    870: adrput( p ) register NODE *p; {
                    871:        register int r;
                    872:        /* output an address, with offsets, from p */
                    873: 
                    874:        if( p->in.op == FLD ){
                    875:                p = p->in.left;
                    876:                }
                    877:        switch( p->in.op ){
                    878: 
                    879:        case NAME:
                    880:                acon( p );
                    881:                return;
                    882: 
                    883:        case ICON:
                    884:                /* addressable value of the constant */
                    885:                putchar('$');
                    886:                acon( p );
                    887:                return;
                    888: 
                    889:        case REG:
                    890:                putstr(rname(p->tn.rval));
                    891:                if(p->in.type == DOUBLE)        /* for entry mask */
                    892:                        (void) rname(p->tn.rval+1);
                    893:                return;
                    894: 
                    895:        case OREG:
                    896:                r = p->tn.rval;
                    897:                if( R2TEST(r) ){ /* double indexing */
                    898:                        register int flags;
                    899: 
                    900:                        flags = R2UPK3(r);
                    901:                        if( flags & 1 ) putchar('*');
                    902:                        if( p->tn.lval != 0 || p->in.name[0] != '\0' ) acon(p);
                    903:                        if( R2UPK1(r) != 100) printf( "(%s)", rname(R2UPK1(r)) );
                    904:                        printf( "[%s]", rname(R2UPK2(r)) );
                    905:                        return;
                    906:                        }
                    907:                if( r == FP && p->tn.lval > 0 ){  /* in the argument region */
                    908:                        if( p->in.name[0] != '\0' ) werror( "bad arg temp" );
                    909:                        printf( CONFMT, p->tn.lval );
                    910:                        putstr( "(fp)" );
                    911:                        return;
                    912:                        }
                    913:                if( p->tn.lval != 0 || p->in.name[0] != '\0') acon( p );
                    914:                printf( "(%s)", rname(p->tn.rval) );
                    915:                return;
                    916: 
                    917:        case UNARY MUL:
                    918:                /* STARNM or STARREG found */
                    919:                if( tshape(p, STARNM) ) {
                    920:                        putchar( '*' );
                    921:                        adrput( p->in.left);
                    922:                        }
                    923:                return;
                    924: 
                    925:        default:
                    926:                cerror( "illegal address" );
                    927:                return;
                    928: 
                    929:                }
                    930: 
                    931:        }
                    932: 
                    933: acon( p ) register NODE *p; { /* print out a constant */
                    934: 
                    935:        if( p->in.name[0] == '\0' ){
                    936:                printf( CONFMT, p->tn.lval);
                    937:                return;
                    938:        } else {
                    939: #ifndef FLEXNAMES
                    940:                printf( "%.8s", p->in.name );
                    941: #else
                    942:                putstr(p->in.name);
                    943: #endif
                    944:                if (p->tn.lval != 0) {
                    945:                        putchar('+');
                    946:                        printf(CONFMT, p->tn.lval);
                    947:                }
                    948:        }
                    949:        }
                    950: 
                    951: genscall( p, cookie ) register NODE *p; {
                    952:        /* structure valued call */
                    953:        return( gencall( p, cookie ) );
                    954:        }
                    955: 
                    956: genfcall( p, cookie ) register NODE *p; {
                    957:        register NODE *p1;
                    958:        register int m;
                    959:        static char *funcops[6] = {
                    960:                "sin", "cos", "sqrt", "exp", "log", "atan"
                    961:        };
                    962: 
                    963:        /* generate function opcodes */
                    964:        if(p->in.op==UNARY FORTCALL && p->in.type==FLOAT &&
                    965:         (p1 = p->in.left)->in.op==ICON &&
                    966:         p1->tn.lval==0 && p1->in.type==INCREF(FTN|FLOAT)) {
                    967: #ifdef FLEXNAMES
                    968:                p1->in.name++;
                    969: #else
                    970:                strcpy(p1->in.name, p1->in.name[1]);
                    971: #endif
                    972:                for(m=0; m<6; m++)
                    973:                        if(!strcmp(p1->in.name, funcops[m]))
                    974:                                break;
                    975:                if(m >= 6)
                    976:                        uerror("no opcode for fortarn function %s", p1->in.name);
                    977:        } else
                    978:                uerror("illegal type of fortarn function");
                    979:        p1 = p->in.right;
                    980:        p->in.op = FORTCALL;
                    981:        if(!canaddr(p1))
                    982:                order( p1, INAREG|INBREG|SOREG|STARREG|STARNM );
                    983:        m = match( p, INTAREG|INTBREG );
                    984:        return(m != MDONE);
                    985: }
                    986: 
                    987: /* tbl */
                    988: int gc_numbytes;
                    989: /* tbl */
                    990: 
                    991: gencall( p, cookie ) register NODE *p; {
                    992:        /* generate the call given by p */
                    993:        register NODE *p1, *ptemp;
                    994:        register int temp, temp1;
                    995:        register int m;
                    996: 
                    997:        if( p->in.right ) temp = argsize( p->in.right );
                    998:        else temp = 0;
                    999: 
                   1000:        if( p->in.op == STCALL || p->in.op == UNARY STCALL ){
                   1001:                /* set aside room for structure return */
                   1002: 
                   1003:                if( p->stn.stsize > temp ) temp1 = p->stn.stsize;
                   1004:                else temp1 = temp;
                   1005:                }
                   1006: 
                   1007:        if( temp > maxargs ) maxargs = temp;
                   1008:        SETOFF(temp1,4);
                   1009: 
                   1010:        if( p->in.right ){ /* make temp node, put offset in, and generate args */
                   1011:                ptemp = talloc();
                   1012:                ptemp->in.op = OREG;
                   1013:                ptemp->tn.lval = -1;
                   1014:                ptemp->tn.rval = SP;
                   1015: #ifndef FLEXNAMES
                   1016:                ptemp->in.name[0] = '\0';
                   1017: #else
                   1018:                ptemp->in.name = "";
                   1019: #endif
                   1020:                ptemp->in.rall = NOPREF;
                   1021:                ptemp->in.su = 0;
                   1022:                genargs( p->in.right, ptemp );
                   1023:                ptemp->in.op = FREE;
                   1024:                }
                   1025: 
                   1026:        p1 = p->in.left;
                   1027:        if( p1->in.op != ICON ){
                   1028:                if( p1->in.op != REG ){
                   1029:                        if( p1->in.op != OREG || R2TEST(p1->tn.rval) ){
                   1030:                                if( p1->in.op != NAME ){
                   1031:                                        order( p1, INAREG );
                   1032:                                        }
                   1033:                                }
                   1034:                        }
                   1035:                }
                   1036: 
                   1037: /* tbl
                   1038:        setup gc_numbytes so reference to ZC works */
                   1039: 
                   1040:        gc_numbytes = temp&(0x3ff);
                   1041: 
                   1042:        p->in.op = UNARY CALL;
                   1043:        m = match( p, INTAREG|INTBREG );
                   1044: 
                   1045:        return(m != MDONE);
                   1046:        }
                   1047: 
                   1048: /* tbl */
                   1049: char *
                   1050: ccbranches[] = {
                   1051:        "eql",
                   1052:        "neq",
                   1053:        "leq",
                   1054:        "lss",
                   1055:        "geq",
                   1056:        "gtr",
                   1057:        "lequ",
                   1058:        "lssu",
                   1059:        "gequ",
                   1060:        "gtru",
                   1061:        };
                   1062: /* tbl */
                   1063: 
                   1064: cbgen( o, lab, mode ) { /*   printf conditional and unconditional branches */
                   1065: 
                   1066:                if(o != 0 && (o < EQ || o > UGT ))
                   1067:                        cerror( "bad conditional branch: %s", opst[o] );
                   1068:                printf( "       j%s     L%d\n",
                   1069:                 o == 0 ? "br" : ccbranches[o-EQ], lab );
                   1070:        }
                   1071: 
                   1072: nextcook( p, cookie ) NODE *p; {
                   1073:        /* we have failed to match p with cookie; try another */
                   1074:        if( cookie == FORREW ) return( 0 );  /* hopeless! */
                   1075:        if( !(cookie&(INTAREG|INTBREG)) ) return( INTAREG|INTBREG );
                   1076:        if( !(cookie&INTEMP) && asgop(p->in.op) ) return( INTEMP|INAREG|INTAREG|INTBREG|INBREG );
                   1077:        return( FORREW );
                   1078:        }
                   1079: 
                   1080: lastchance( p, cook ) NODE *p; {
                   1081:        /* forget it! */
                   1082:        return(0);
                   1083:        }
                   1084: 
                   1085: optim2( p ) register NODE *p; {
                   1086: # ifdef ONEPASS
                   1087:        /* do local tree transformations and optimizations */
                   1088: # define RV(p) p->in.right->tn.lval
                   1089: # define nncon(p)      ((p)->in.op == ICON && (p)->in.name[0] == 0)
                   1090:        register int o, i;
                   1091:        register NODE *l, *r;
                   1092: 
                   1093:        switch (o = p->in.op) {
                   1094: 
                   1095:        case DIV: case ASG DIV:
                   1096:        case MOD: case ASG MOD:
                   1097:                /*
                   1098:                 * Change unsigned mods and divs to
                   1099:                 * logicals (mul is done in mip & c2)
                   1100:                 */
                   1101:                if (ISUNSIGNED(p->in.left->in.type) && nncon(p->in.right) &&
                   1102:                    (i = ispow2(RV(p))) >= 0) {
                   1103:                        if (o == DIV || o == ASG DIV) {
                   1104:                                p->in.op = RS;
                   1105:                                RV(p) = i;
                   1106:                        } else {
                   1107:                                p->in.op = AND;
                   1108:                                RV(p)--;
                   1109:                        }
                   1110:                        if (asgop(o))
                   1111:                                p->in.op = ASG p->in.op;
                   1112:                }
                   1113:                return;
                   1114: 
                   1115:        case SCONV:
                   1116:                l = p->in.left;
                   1117:                /* clobber conversions w/o side effects */
                   1118:                if (!anyfloat(p, l) && l->in.op != PCONV &&
                   1119:                    tlen(p) == tlen(l)) {
                   1120:                        if (l->in.op != FLD)
                   1121:                                l->in.type = p->in.type;
                   1122:                        ncopy(p, l);
                   1123:                        l->in.op = FREE;
                   1124:                }
                   1125:                return;
                   1126: 
                   1127:        case ASSIGN:
                   1128:                /*
                   1129:                 * Try to zap storage conversions of non-float items.
                   1130:                 */
                   1131:                r = p->in.right;
                   1132:                if (r->in.op == SCONV && !anyfloat(r->in.left, r)) {
                   1133:                        int wdest, wconv, wsrc;
                   1134:                        wdest = tlen(p->in.left);
                   1135:                        wconv = tlen(r);
                   1136:                        /*
                   1137:                         * If size doesn't change across assignment or
                   1138:                         * conversion expands src before shrinking again
                   1139:                         * due to the assignment, delete conversion so
                   1140:                         * code generator can create optimal code.
                   1141:                         */
                   1142:                        if (wdest == wconv ||
                   1143:                         (wdest == (wsrc = tlen(r->in.left)) && wconv > wsrc)) {
                   1144:                                p->in.right = r->in.left;
                   1145:                                r->in.op = FREE;
                   1146:                        }
                   1147:                }
                   1148:                return;
                   1149:        }
                   1150: # endif
                   1151: }
                   1152: 
                   1153: struct functbl {
                   1154:        int fop;
                   1155:        char *func;
                   1156: } opfunc[] = {
                   1157:        DIV,            "udiv", 
                   1158:        ASG DIV,        "udiv", 
                   1159:        0
                   1160: };
                   1161: 
                   1162: hardops(p)  register NODE *p; {
                   1163:        /* change hard to do operators into function calls.  */
                   1164:        register NODE *q;
                   1165:        register struct functbl *f;
                   1166:        register int o;
                   1167:        register TWORD t, t1, t2;
                   1168: 
                   1169:        o = p->in.op;
                   1170: 
                   1171:        for( f=opfunc; f->fop; f++ ) {
                   1172:                if( o==f->fop ) goto convert;
                   1173:        }
                   1174:        return;
                   1175: 
                   1176:        convert:
                   1177:        t = p->in.type;
                   1178:        t1 = p->in.left->in.type;
                   1179:        t2 = p->in.right->in.type;
                   1180: 
                   1181:        if (!((ISUNSIGNED(t1) && !(ISUNSIGNED(t2))) || 
                   1182:             ( t2 == UNSIGNED))) return;
                   1183: 
                   1184:        /* need to rewrite tree for ASG OP */
                   1185:        /* must change ASG OP to a simple OP */
                   1186:        if( asgop( o ) ) {
                   1187:                q = talloc();
                   1188:                q->in.op = NOASG ( o );
                   1189:                q->in.rall = NOPREF;
                   1190:                q->in.type = p->in.type;
                   1191:                q->in.left = tcopy(p->in.left);
                   1192:                q->in.right = p->in.right;
                   1193:                p->in.op = ASSIGN;
                   1194:                p->in.right = q;
                   1195:                zappost(q->in.left); /* remove post-INCR(DECR) from new node */
                   1196:                fixpre(q->in.left);     /* change pre-INCR(DECR) to +/- */
                   1197:                p = q;
                   1198: 
                   1199:        }
                   1200:        /* turn logicals to compare 0 */
                   1201:        else if( logop( o ) ) {
                   1202:                ncopy(q = talloc(), p);
                   1203:                p->in.left = q;
                   1204:                p->in.right = q = talloc();
                   1205:                q->in.op = ICON;
                   1206:                q->in.type = INT;
                   1207: #ifndef FLEXNAMES
                   1208:                q->in.name[0] = '\0';
                   1209: #else
                   1210:                q->in.name = "";
                   1211: #endif
                   1212:                q->tn.lval = 0;
                   1213:                q->tn.rval = 0;
                   1214:                p = p->in.left;
                   1215:        }
                   1216: 
                   1217:        /* build comma op for args to function */
                   1218:        t1 = p->in.left->in.type;
                   1219:        t2 = 0;
                   1220:        if ( optype(p->in.op) == BITYPE) {
                   1221:                q = talloc();
                   1222:                q->in.op = CM;
                   1223:                q->in.rall = NOPREF;
                   1224:                q->in.type = INT;
                   1225:                q->in.left = p->in.left;
                   1226:                q->in.right = p->in.right;
                   1227:                t2 = p->in.right->in.type;
                   1228:        } else
                   1229:                q = p->in.left;
                   1230: 
                   1231:        p->in.op = CALL;
                   1232:        p->in.right = q;
                   1233: 
                   1234:        /* put function name in left node of call */
                   1235:        p->in.left = q = talloc();
                   1236:        q->in.op = ICON;
                   1237:        q->in.rall = NOPREF;
                   1238:        q->in.type = INCREF( FTN + p->in.type );
                   1239: #ifndef FLEXNAMES
                   1240:                strcpy( q->in.name, f->func );
                   1241: #else
                   1242:                q->in.name = f->func;
                   1243: #endif
                   1244:        q->tn.lval = 0;
                   1245:        q->tn.rval = 0;
                   1246: 
                   1247:        }
                   1248: 
                   1249: zappost(p) NODE *p; {
                   1250:        /* look for ++ and -- operators and remove them */
                   1251: 
                   1252:        register int o, ty;
                   1253:        register NODE *q;
                   1254:        o = p->in.op;
                   1255:        ty = optype( o );
                   1256: 
                   1257:        switch( o ){
                   1258: 
                   1259:        case INCR:
                   1260:        case DECR:
                   1261:                        q = p->in.left;
                   1262:                        p->in.right->in.op = FREE;  /* zap constant */
                   1263:                        ncopy( p, q );
                   1264:                        q->in.op = FREE;
                   1265:                        return;
                   1266: 
                   1267:                }
                   1268: 
                   1269:        if( ty == BITYPE ) zappost( p->in.right );
                   1270:        if( ty != LTYPE ) zappost( p->in.left );
                   1271: }
                   1272: 
                   1273: fixpre(p) NODE *p; {
                   1274: 
                   1275:        register int o, ty;
                   1276:        o = p->in.op;
                   1277:        ty = optype( o );
                   1278: 
                   1279:        switch( o ){
                   1280: 
                   1281:        case ASG PLUS:
                   1282:                        p->in.op = PLUS;
                   1283:                        break;
                   1284:        case ASG MINUS:
                   1285:                        p->in.op = MINUS;
                   1286:                        break;
                   1287:                }
                   1288: 
                   1289:        if( ty == BITYPE ) fixpre( p->in.right );
                   1290:        if( ty != LTYPE ) fixpre( p->in.left );
                   1291: }
                   1292: 
                   1293: NODE * addroreg(l) NODE *l;
                   1294:                                /* OREG was built in clocal()
                   1295:                                 * for an auto or formal parameter
                   1296:                                 * now its address is being taken
                   1297:                                 * local code must unwind it
                   1298:                                 * back to PLUS/MINUS REG ICON
                   1299:                                 * according to local conventions
                   1300:                                 */
                   1301: {
                   1302:        cerror("address of OREG taken");
                   1303: }
                   1304: 
                   1305: # ifndef ONEPASS
                   1306: main( argc, argv ) char *argv[]; {
                   1307:        return( mainp2( argc, argv ) );
                   1308:        }
                   1309: # endif
                   1310: 
                   1311: strip(p) register NODE *p; {
                   1312:        NODE *q;
                   1313: 
                   1314:        /* strip nodes off the top when no side effects occur */
                   1315:        for( ; ; ) {
                   1316:                switch( p->in.op ) {
                   1317:                case SCONV:                     /* remove lint tidbits */
                   1318:                        q = p->in.left;
                   1319:                        ncopy( p, q );
                   1320:                        q->in.op = FREE;
                   1321:                        break;
                   1322:                /* could probably add a few more here */
                   1323:                default:
                   1324:                        return;
                   1325:                        }
                   1326:                }
                   1327:        }
                   1328: 
                   1329: myreader(p) register NODE *p; {
                   1330:        strip( p );             /* strip off operations with no side effects */
                   1331:        walkf( p, hardops );    /* convert ops to function calls */
                   1332:        canon( p );             /* expands r-vals for fileds */
                   1333:        walkf( p, optim2 );
                   1334:        }

unix.superglobalmegacorp.com

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