Annotation of cci/usr/src/usr.bin/f77/f77pass2/local2.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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