Annotation of researchv9/cmd/sun/pcc/util2.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char sccsid[] = "@(#)util2.c 1.1 86/02/03 Copyr 1985 Sun Micro";
                      3: #endif
                      4: 
                      5: /*
                      6:  * Copyright (c) 1985 by Sun Microsystems, Inc.
                      7:  */
                      8: 
                      9: #include "cpass2.h"
                     10: #include "ctype.h"
                     11: 
                     12: /* 
                     13:  *     garbage ripped out of local2.68, which was huge
                     14:  */
                     15: # ifdef FORT
                     16: int ftlab1, ftlab2;
                     17: # endif
                     18: /* a lot of the machine dependent parts of the second pass */
                     19: #ifdef FORT
                     20: #   define fltfun 0
                     21: #else
                     22:     extern int fltfun;
                     23: #endif
                     24: 
                     25: #ifndef ONEPASS                        /* 2nd pass of (possibly) several compilers */
                     26:     char pcname[]= "pc0";      /* name passed by pc command    */
                     27:     int pascal=0;              /* = 1 if compiling pascal      */
                     28: #endif
                     29: 
                     30: # define BITMASK(n) ((1L<<(n))-1)
                     31: 
                     32: /* output forms for floating point constants */
                     33: typedef enum {
                     34:        F_hex, F_eformat, F_loworder, F_highorder
                     35: } Floatform;
                     36: 
                     37: void adrput();
                     38: static void fcon();
                     39: static void dumpfcons();
                     40: 
                     41: void
                     42: print_d(value)
                     43:        register int value;
                     44: {      
                     45:        char buffer[8]; 
                     46:        register char *p= buffer+8; 
                     47:        register int i= 0;
                     48: 
                     49:        if (value == 0) {
                     50:                putchar('0'); 
                     51:                return;
                     52:        }
                     53:        if (value < 0) {
                     54:                putchar('-'); 
                     55:                value= -value;
                     56:        }
                     57:        if (value <= 32767) { 
                     58:                register short v= value;
                     59:                while (v != 0) {
                     60:                        *--p= (v % 10) + '0';
                     61:                        v /= 10; 
                     62:                        i++; 
                     63:                }
                     64:        } else {
                     65:                while (value != 0) {
                     66:                        *--p= (value % 10) + '0';
                     67:                        value /= 10; 
                     68:                        i++; 
                     69:                }
                     70:        }
                     71:        for(; i>0; i--)
                     72:                putchar(*p++);
                     73: }
                     74: 
                     75: void
                     76: print_x(value)
                     77:        register unsigned value;
                     78: {      
                     79:        char buffer[8]; 
                     80:        register char *p= buffer+8; 
                     81:        register int i= 0;
                     82: 
                     83:        if (value == 0) {
                     84:                putchar('0'); 
                     85:                return;
                     86:        }
                     87:        if ((int)value < 0) {
                     88:                value = -value;
                     89:                putchar('-'); 
                     90:        }
                     91:        while (value != 0) {
                     92:                *--p = "0123456789abcdef"[value & 0xf];
                     93:                value >>= 4;
                     94:                i++; 
                     95:        }
                     96:        putchar('0'); 
                     97:        putchar('x');
                     98:        fwrite(p, 1, i, stdout);
                     99: }
                    100: 
                    101: void
                    102: print_str(s)
                    103:        char *s;
                    104: {
                    105:        fputs(s, stdout);
                    106: }
                    107: 
                    108: void
                    109: print_str_nl(s)
                    110:        char *s;
                    111: {
                    112:        puts(s);
                    113: }
                    114: 
                    115: void
                    116: print_str_d(s, d)
                    117:        char *s;
                    118:        int d;
                    119: {
                    120:        fputs(s, stdout);
                    121:        print_d(d);
                    122: }
                    123: 
                    124: void
                    125: print_str_d_nl(s, d)
                    126:        char *s;
                    127:        int d;
                    128: {
                    129:        fputs(s, stdout);
                    130:        print_d(d);
                    131:        putchar('\n');
                    132: }
                    133: 
                    134: void
                    135: print_str_str(s1, s2)
                    136:        char *s1, *s2;
                    137: {
                    138:        fputs(s1, stdout);
                    139:        fputs(s2, stdout);
                    140: }
                    141: 
                    142: void
                    143: print_str_str_nl(s1, s2)
                    144:        char *s1, *s2;
                    145: {
                    146:        fputs(s1, stdout);
                    147:        puts(s2);
                    148: }
                    149: 
                    150: void print_label(l)
                    151:        int l;
                    152: {
                    153:        putchar('L');
                    154:        print_d(l);
                    155:        putchar(':');
                    156: }
                    157: 
                    158: where(c)
                    159: {
                    160:        fprintf( stderr, "%s, line %d: ", filename, lineno );
                    161: }
                    162: 
                    163: lineid( l, fn )
                    164:        char *fn; 
                    165: {
                    166:        /* identify line l and file fn */
                    167:        printf( "|      line %d, file %s\n", l, fn );
                    168: }
                    169: 
                    170: epr(p)
                    171:        NODE *p;
                    172: {
                    173:        extern fwalk();
                    174:        fwalk(p, eprint, 0);
                    175: }
                    176: 
                    177: int    usedregs; /* Flag word for registers used in current routine */
                    178: int    usedfpregs;     /* Flag word for floating point registers */
                    179: int toff, maxtoff;
                    180: 
                    181: cntbits(i)
                    182:        register int i;
                    183: {
                    184:        register int j,ans;
                    185: 
                    186:        for (ans=0, j=0; i!=0 && j<16; j++) { 
                    187:                if (i&1) ans++; 
                    188:                i >>= 1 ; 
                    189:        }
                    190:        return(ans);
                    191: }
                    192: 
                    193: /*
                    194:  * allocate storage for register save areas
                    195:  * and generate routine epilogs.  The d/a register
                    196:  * save area is always the LAST section of an
                    197:  * activation record. A label equated to its offset
                    198:  * is used to create the activation record at runtime.
                    199:  */
                    200: eobl2()
                    201: {
                    202:        OFFSZ regsave_off;      /* a6-relative offset of areg/dreg save area */
                    203:        OFFSZ fp_regsave_off;   /* a6-relative offset of fp reg save area */
                    204:        OFFSZ spoff;            /* a6-relative offset of local vars/temps */
                    205: 
                    206: #      ifndef FORT
                    207:            extern int ftlab1, ftlab2;
                    208: #      endif
                    209: 
                    210: #      ifdef FREETEMP
                    211:            spoff = maxoff + maxtemp;
                    212: #      else
                    213:            spoff = maxoff;
                    214: #      endif FREETEMP
                    215: 
                    216:        spoff /= SZCHAR;
                    217:        SETOFF(spoff,sizeof(long));
                    218:        /*
                    219:         * set masks for saving/restoring registers
                    220:         */
                    221:        usedregs &= REGVARMASK;
                    222:        usedfpregs &= FREGVARMASK;
                    223:        /*
                    224:         * allocate storage for register save areas
                    225:         */
                    226:        fp_regsave_off = regsave_off = spoff;
                    227:        if (use68881 && usedfpregs) {
                    228:                fp_regsave_off += (SZEXTENDED/SZCHAR)*cntbits(usedfpregs);
                    229:                regsave_off = fp_regsave_off;
                    230:        }
                    231:        if (usedregs) {
                    232:                regsave_off += (SZLONG/SZCHAR)*cntbits(usedregs);
                    233:        }
                    234:        /*
                    235:         * generate epilogue
                    236:         */
                    237:        printf( "LE%d:\n",ftnno);
                    238:        if (use68881 && usedfpregs) {
                    239:                /*
                    240:                 * restore floating point registers.
                    241:                 */
                    242:                if (fp_regsave_off > 32767) {
                    243:                        /* long offset */
                    244:                        if (use68020) {
                    245:                                printf("        fmovem  a6@(-0x%x:l),#0x%x\n",
                    246:                                        fp_regsave_off, usedfpregs);
                    247:                        } else {
                    248:                                /*
                    249:                                 * 68881 but no 68020; I doubt this will
                    250:                                 * ever happen, but just in case...
                    251:                                 */
                    252:                                printf("        movl    #-0x%x,a0\n",
                    253:                                        fp_regsave_off);
                    254:                                printf("        fmovem  a6@(0,a0:l),#0x%x",
                    255:                                        usedfpregs);
                    256:                        }
                    257:                } else {
                    258:                        /* short offset */
                    259:                        printf("        fmovem  a6@(-0x%x),#0x%x\n",
                    260:                                fp_regsave_off, usedfpregs);
                    261:                }
                    262:        } /* usedfpregs */
                    263:        if (usedregs) {
                    264:                /*
                    265:                 * restore data and address registers
                    266:                 */
                    267:                if (regsave_off > 32767) {
                    268:                        /* long offset */
                    269:                        if (use68020) {
                    270:                                printf( "       moveml  a6@(-0x%x:l),#0x%x\n",
                    271:                                        regsave_off, usedregs );
                    272:                        } else {
                    273:                                printf("        movl    #-0x%x,a0\n",
                    274:                                        regsave_off);
                    275:                                printf("        moveml  a6@(0,a0:l),#0x%x\n",
                    276:                                        usedregs);
                    277:                        }
                    278:                } else {
                    279:                        /* short offset */
                    280:                        printf( "       moveml  a6@(-0x%x),#0x%x\n",
                    281:                                regsave_off, usedregs );
                    282:                }
                    283:        } /* usedregs */
                    284:        printf( "       unlk    a6\n    rts\n" );
                    285:        printf( "       LF%d = %ld\n", ftnno, regsave_off );
                    286:        printf( "       LS%d = 0x%x\n", ftnno, usedregs );
                    287:        printf( "       LFF%d = %ld\n", ftnno, fp_regsave_off );
                    288:        printf( "       LSS%d = 0x%x\n", ftnno, usedfpregs );
                    289: #      ifdef FREETEMP
                    290:            printf("    LT%d = 0x%x\n", ftnno,
                    291:                cntbits(usedregs)*(SZINT/SZCHAR));
                    292: #      endif
                    293: #      ifdef STACKPROBE
                    294:            printf("    LP%d =  0x%x\n", ftnno, maxtoff+8 );
                    295: #      endif
                    296:        maxtoff = 0;
                    297:        usedregs = 0;
                    298:        usedfpregs = 0;
                    299:        dumpfcons();
                    300: }
                    301: 
                    302: struct hoptab { int opmask; char * opstring; } ioptab[] = {
                    303: 
                    304:        ASG PLUS, "add",
                    305:        ASG MINUS, "sub",
                    306:        ASG OR, "or",
                    307:        ASG AND, "and",
                    308:        ASG ER, "eor",
                    309:        ASG MUL, "mul",
                    310:        ASG DIV, "div",
                    311:        ASG MOD, "div",
                    312:        ASG LS, "sl",
                    313:        ASG RS, "sr",
                    314:        -1, ""    };
                    315: 
                    316: hopcode( f, o )
                    317: {
                    318:        /* output the appropriate string from the above table */
                    319: 
                    320:        register struct hoptab *q;
                    321: 
                    322:        for( q = ioptab;  q->opmask>=0; ++q ){
                    323:                if( q->opmask == o ){
                    324:                        if( f == 'F') putchar('f');
                    325:                        printf(q->opstring);
                    326:                        return;
                    327:                        }
                    328:                }
                    329:        cerror( "no hoptab for %s", opst[o] );
                    330: }
                    331: 
                    332: char *
                    333: rnames[] = {  /* keyed to register number tokens */
                    334:        "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
                    335:        "a0", "a1", "a2", "a3", "a4", "a5", "a6", "sp",
                    336:        "fp0", "fp1", "fp2", "fp3", "fp4", "fp5", "fp6", "fp7"
                    337:        };
                    338: 
                    339: int rstatus[] = {
                    340:        SAREG|STAREG,   SAREG|STAREG,
                    341:        SAREG|STAREG,   SAREG|STAREG,
                    342:        SAREG|STAREG,   SAREG|STAREG,
                    343:        SAREG|STAREG,   SAREG|STAREG,
                    344: 
                    345:        SBREG|STBREG,   SBREG|STBREG,
                    346:        SBREG|STBREG,   SBREG|STBREG,
                    347:        SBREG|STBREG,   SBREG|STBREG,
                    348:        SBREG,          SBREG,
                    349: 
                    350:        SCREG|STCREG,   SCREG|STCREG,
                    351:        SCREG|STCREG,   SCREG|STCREG,
                    352:        SCREG|STCREG,   SCREG|STCREG,
                    353:        SCREG|STCREG,   SCREG|STCREG,
                    354:     };
                    355: 
                    356: tlen(p) NODE *p;
                    357: {
                    358:        switch(p->in.type) {
                    359:                case CHAR:
                    360:                case UCHAR:
                    361:                        return(SZCHAR/SZCHAR);
                    362: 
                    363:                case SHORT:
                    364:                case USHORT:
                    365:                        return(SZSHORT/SZCHAR);
                    366: 
                    367:                case DOUBLE:
                    368:                        return(SZDOUBLE/SZCHAR);
                    369: 
                    370:                default:
                    371:                        return(SZINT/SZCHAR);
                    372:                }
                    373: }
                    374: 
                    375: 
                    376: rmove( rt, rs, t )
                    377:        register int rt,rs;
                    378: {
                    379:        int fsrce, fdest;
                    380: 
                    381:        fsrce = iscreg(rs);
                    382:        fdest = iscreg(rt);
                    383:        if (!fsrce && !fdest) {
                    384:                /*
                    385:                 * neither source nor dest is on the coprocessor
                    386:                 */
                    387:                if ( t==DOUBLE ){
                    388:                        printf("        movl    %s,%s\n movl    %s,%s\n",
                    389:                                rnames[rs], rnames[rt],
                    390:                                rnames[rs+1], rnames[rt+1]);
                    391:                        markused(rs+1);
                    392:                        markused(rt+1);
                    393:                } else {
                    394:                        /* the most common case */
                    395:                        printf("        movl    %s,%s\n",
                    396:                                rnames[rs], rnames[rt] );
                    397:                }
                    398:        } else if (fsrce && !fdest) {
                    399:                /*
                    400:                 * source is on coprocessor, dest isn't
                    401:                 */
                    402:                if (t == DOUBLE) {
                    403:                        /* royal pain; must use memory */
                    404:                        printf("        fmoved  %s,sp@-\n", rnames[rs]);
                    405:                        printf("        movl    sp@+,%s\n", rnames[rt]);
                    406:                        printf("        movl    sp@+,%s\n", rnames[rt+1]);
                    407:                        markused(rt+1);
                    408:                } else {
                    409:                        /* t == FLOAT */
                    410:                        printf("        fmoves  %s,%s\n",
                    411:                            rnames[rs], rnames[rt]);
                    412:                }
                    413:        } else if (!fsrce && fdest) {
                    414:                /*
                    415:                 * source isn't on coprocessor, dest is
                    416:                 */
                    417:                if (t == DOUBLE) {
                    418:                        /* royal pain; must use memory */
                    419:                        printf("        movl    %s,sp@-\n", rnames[rs+1]);
                    420:                        printf("        movl    %s,sp@-\n", rnames[rs]);
                    421:                        printf("        fmoved  sp@+,%s\n", rnames[rt]);
                    422:                        markused(rs+1);
                    423:                } else {
                    424:                        /* t == FLOAT */
                    425:                        printf("        fmoves  %s,%s\n",
                    426:                            rnames[rs], rnames[rt]);
                    427:                }
                    428:        } else {
                    429:                /*
                    430:                 * both regs are on the coprocessor
                    431:                 */
                    432:                printf("        fmovex  %s,%s\n", rnames[rs], rnames[rt]);
                    433:        }
                    434:        markused(rs);
                    435:        markused(rt);
                    436: }
                    437: 
                    438: struct respref
                    439: respref[] = {
                    440:        INCREG|INTCREG, INCREG|INTCREG,
                    441:        INTAREG|INTBREG,INTAREG|INTBREG,
                    442:        INAREG|INBREG,  INAREG|INBREG,
                    443:        INAREG|INBREG,  SZERO,
                    444:        INAREG|INBREG,  SOREG|STARREG|STARNM|SNAME|SCON,
                    445:        INTEMP,         INTEMP,
                    446:        FORARG,         FORARG,
                    447:        INTAREG,        SOREG|SNAME|SAREG|SBREG,
                    448:        0,      0 };
                    449: 
                    450: #ifdef FORT
                    451: /*
                    452:  * save register variables.
                    453:  * Use labels since we don't know
                    454:  * which ones are being used until
                    455:  * the end of the function.
                    456:  */
                    457: saveregs()
                    458: {
                    459:        printf("        link    a6,#0\n");
                    460:        printf("        addl    #-LF%d,sp\n", ftnno);
                    461:        printf("        moveml  #LS%d,sp@\n",ftnno);
                    462:        if (use68881) {
                    463:                /*
                    464:                 * save floating registers used for variables
                    465:                 */
                    466:                if (use68020) {
                    467:                        printf("        fmovem  #LSS%d,a6@(-LFF%d:l)\n",
                    468:                                ftnno, ftnno);
                    469:                } else {
                    470:                        /* 68881 without 68020; unlikely combination */
                    471:                        printf("        movl    #-LFF%d,a0\n", ftnno);
                    472:                        printf("        fmovem  #LSS%d,a6@(0,a0:l)\n", ftnno);
                    473:                }
                    474:        }
                    475: }
                    476: #endif FORT
                    477: 
                    478: 
                    479: /*
                    480:  * Set up temporary registers.
                    481:  * Use any left over from register
                    482:  * variable allocation for scratch.
                    483:  */
                    484: 
                    485: setregs()
                    486: {
                    487:        register i;
                    488:        int nextdreg;
                    489:        int nextareg;
                    490:        int nextfreg;
                    491: 
                    492:        extern int skybase;
                    493: 
                    494:        nextdreg = NEXTD(maxtreg);
                    495:        nextareg = NEXTA(maxtreg);
                    496:        nextfreg = NEXTF(maxtreg);
                    497: 
                    498: #      ifdef FORT
                    499:            /* reg reserved by iropt for __skybase */
                    500:            skybase  = SKYBASE(maxtreg);
                    501:            if (nextdreg == D0)
                    502:                nextdreg = MAX_DVAR;
                    503:            if (nextareg == A0)
                    504:                nextareg = MAX_AVAR;
                    505:            if (nextfreg == FP0)
                    506:                nextfreg = MAX_FVAR;
                    507: #      endif FORT
                    508: 
                    509: #      ifdef FREETEMP
                    510:            tmpoff = 0; /* we number temp regsters differently here */
                    511: #      endif
                    512: 
                    513:        for( i=MIN_DVAR; i<=MAX_DVAR; i++ ){
                    514:                rstatus[i] = i <= nextdreg ? SAREG|STAREG : SAREG;
                    515: #              ifdef FORT
                    516:                    if (i > nextdreg)
                    517:                        markused(i);
                    518: #              endif
                    519:        }
                    520:        for( i=MIN_AVAR; i<=MAX_AVAR; i++ ){
                    521:                rstatus[i] = i <= nextareg ? SBREG|STBREG : SBREG;
                    522: #              ifdef FORT
                    523:                    if (i > nextareg)
                    524:                        markused(i);
                    525: #              endif
                    526:        }
                    527:        for( i=MIN_FVAR; i<=MAX_FVAR; i++ ){
                    528:                rstatus[i] = i <= nextfreg ? SCREG|STCREG : SCREG;
                    529: #              ifdef FORT
                    530:                    if (i > nextfreg)
                    531:                        markused(i);
                    532: #              endif
                    533:        }
                    534: 
                    535:        fregs.d = (nextdreg - D0) + 1;
                    536:        fregs.a = (nextareg - A0) + 1;
                    537:        fregs.f = (nextfreg - FP0) + 1;
                    538: 
                    539:        if( xdebug ){
                    540:                /* -x changes number of free regs to 2, -xx to 3, etc. */
                    541:                if( (xdebug+1) < fregs.f ) fregs.f = xdebug+1;
                    542:        }
                    543: }
                    544: 
                    545: shltype( o, p )
                    546:        register o;
                    547:        NODE *p; 
                    548: {
                    549:        return( o== REG || o == NAME || o == ICON || o == OREG || o == FCON
                    550:                || ( o==UNARY MUL && shumul(p->in.left)) );
                    551: }
                    552: 
                    553: flshape( p ) register NODE *p; 
                    554: {
                    555:        register o = p->in.op;
                    556:        if( o==NAME || o==REG || o==ICON || o==OREG ) return( 1 );
                    557:        return( o==UNARY MUL && shumul(p->in.left)==STARNM );
                    558: }
                    559: 
                    560: shtemp( p ) register NODE *p; 
                    561: {
                    562:        if( p->in.op == UNARY MUL ) p = p->in.left;
                    563:        if( p->in.op == REG )
                    564:                return( !istreg( p->tn.rval ) );
                    565:        if( p->in.op == OREG && !R2TEST(p->tn.rval) )
                    566:                return( !istreg( p->tn.rval ) );
                    567:        return( p->in.op == NAME || p->in.op == ICON );
                    568: }
                    569: 
                    570: spsz( t, v ) TWORD t; CONSZ v; 
                    571: {
                    572: 
                    573:        /* is v the size to increment something of type t */
                    574: 
                    575:        if( !ISPTR(t) ) return( 0 );
                    576:        t = DECREF(t);
                    577: 
                    578:        if( ISPTR(t) ) return( v == (SZPOINT/SZCHAR) );
                    579: 
                    580:        switch( t ){
                    581: 
                    582:        case UCHAR:
                    583:        case CHAR:
                    584:                return( v == 1 );
                    585: 
                    586:        case SHORT:
                    587:        case USHORT:
                    588:                return( v == (SZSHORT/SZCHAR) );
                    589: 
                    590:        case INT:
                    591:        case UNSIGNED:
                    592:        case FLOAT:
                    593:                return( v == (SZINT/SZCHAR) );
                    594: 
                    595:        case DOUBLE:
                    596:                return( v == (SZDOUBLE/SZCHAR) );
                    597:                }
                    598: 
                    599:        return( 0 );
                    600: }
                    601: 
                    602: indexreg( p ) register NODE *p; 
                    603: {
                    604:        if( p->in.op == REG && p->tn.rval >= A0 && p->tn.rval <= SP ) return(1);
                    605:        return(0);
                    606: }
                    607: 
                    608: shumul( p ) register NODE *p; 
                    609: {
                    610:        register o;
                    611:        extern int xdebug;
                    612: 
                    613:        if (xdebug) {
                    614:             printf("\nshumul:op=%d, ", p->in.op);
                    615:             switch (optype(p->in.op)){
                    616:            case BITYPE:
                    617:                        printf( " rop=%d, rname=%s, rlval=%D", 
                    618:                            p->in.right->in.op, p->in.right->in.name,  
                    619:                            p->in.right->tn.lval);
                    620:                        /* fall through */
                    621:            default:
                    622:                        printf( "lop=%d, plty=%d ", 
                    623:                            p->in.left->in.op, p->in.left->in.type );
                    624:            case LTYPE: ; /* do nothing */
                    625:            }
                    626:            putchar('\n');
                    627:        }
                    628: 
                    629: 
                    630:        o = p->in.op;
                    631:        if( indexreg(p) )
                    632:                return( STARNM );
                    633: 
                    634:        if( o == INCR && indexreg(p->in.left) && p->in.right->in.op == ICON &&
                    635:            p->in.right->in.name[0] == '\0' &&
                    636:            spsz( p->in.left->in.type, p->in.right->tn.lval ) )
                    637:                return( STARREG );
                    638:        if( o == ASG MINUS  && indexreg(p->in.left) && p->in.right->in.op == ICON &&
                    639:            p->in.right->in.name[0] == '\0' &&
                    640:            spsz( p->in.left->in.type, p->in.right->tn.lval ) )
                    641:                return( STARREG );
                    642: 
                    643:        return( 0 );
                    644: }
                    645: 
                    646: adrcon( val ) CONSZ val; 
                    647: {
                    648:        printf( CONFMT, val );
                    649: }
                    650: 
                    651: /* put out a floating e-format constant */
                    652: 
                    653: floatimmed(p)
                    654:        NODE *p;
                    655: {
                    656:        putchar('#');
                    657:        fcon( p, F_eformat );
                    658: }
                    659: 
                    660: conput( p ) register NODE *p; 
                    661: {
                    662:        switch( p->in.op ){
                    663:        case FCON:
                    664:                fcon( p, F_hex );
                    665:                return;
                    666: 
                    667:        case ICON:
                    668:                acon( p );
                    669:                return;
                    670: 
                    671:        default:
                    672:                cerror( "illegal conput" );
                    673:        }
                    674: }
                    675: 
                    676: /*
                    677:  * put out an explicit length qualifier.  This simplifies
                    678:  * handling of offsets in the 68020 assembler somewhat.
                    679:  */
                    680: offsize(p)
                    681:        register NODE *p;
                    682: {
                    683:        if ( p->tn.name[0] != '\0' || p->tn.lval > 32767
                    684:            || p->tn.lval < -32768 ) {
                    685:                printf(":l");
                    686:        }
                    687: }
                    688: 
                    689: oregput(p)
                    690:        register NODE *p;
                    691: {
                    692:        register r;
                    693: 
                    694:        r = p->tn.rval;
                    695:        if (R2TEST(r)) {
                    696:                /*
                    697:                 * double indexing
                    698:                 */
                    699:                if (use68020) {
                    700:                        /*
                    701:                         * For 68020, R2UPK3 encodes the following data:
                    702:                         *      int shortx:1; short index
                    703:                         *      int ibit:1; memory indirect mode (ignored)
                    704:                         *      int scale:4; scale factor (1,2,4,8)
                    705:                         */
                    706:                        register flags;
                    707:                        int base, index, scale, shortx, indirect;
                    708: 
                    709:                        base = R2UPK1(r);
                    710:                        index = R2UPK2(r);
                    711:                        markused(base);
                    712:                        markused(index);
                    713:                        flags = R2UPK3(r);
                    714:                        R2UPKFLGS(flags,shortx,indirect,scale);
                    715:                        /*
                    716:                         * print base register and displacement (if any)
                    717:                         */
                    718:                        printf(rnames[base]);
                    719:                        printf("@(");
                    720:                        acon(p);              /* base displacement */
                    721:                        offsize(p);           /* size of displacement */
                    722:                        putchar(',');
                    723:                        /*
                    724:                         * print index register and scale factor.  For now,
                    725:                         * we assume all indices have been long-extended.
                    726:                         */
                    727:                        printf(rnames[index]);
                    728:                        putchar(':');
                    729:                        putchar(shortx? 'w' : 'l');
                    730:                        switch(scale) {
                    731:                        case 0:
                    732:                        case 1:
                    733:                                break;
                    734:                        case 2:
                    735:                        case 4:
                    736:                        case 8:
                    737:                                printf(":%d",scale);
                    738:                                break;
                    739:                        default:
                    740:                                cerror("illegal scale factor (%d)", scale);
                    741:                                /*NOTREACHED*/
                    742:                        }
                    743:                        putchar(')');
                    744:                } /* use68020 */ 
                    745:                else {
                    746:                        /*
                    747:                         * For the 68010, R2UPK3 encodes only whether
                    748:                         * a short index is used.
                    749:                         */
                    750:                        int base, index, flags, shortx, ignored;
                    751:                        base = R2UPK1(p->tn.rval);
                    752:                        index = R2UPK2(p->tn.rval);
                    753:                        flags = R2UPK3(p->tn.rval);
                    754:                        R2UPKFLGS(flags,shortx,ignored,ignored);
                    755:                        printf( "%s@(%d,%s:%c)",
                    756:                                rnames[base],                   /* breg */
                    757:                                p->tn.lval,                     /* disp */
                    758:                                rnames[index],                  /* xreg */
                    759:                                shortx ? 'w' : 'l' );           /* xlen */
                    760:                        markused(base);
                    761:                        markused(index);
                    762:                }
                    763:        } 
                    764:        else {
                    765:                int base = R2UPK2(p->tn.rval);
                    766:                markused(base);
                    767:                printf( rnames[base] );
                    768:                putchar('@');
                    769:                if( p->tn.lval != 0 || p->in.name[0] != '\0' ) { 
                    770:                        putchar('('); 
                    771:                        acon( p ); 
                    772:                        if (use68020) offsize( p );
                    773:                        putchar(')'); 
                    774:                } /* if */
                    775:        } /* else */
                    776: } /* oregput */
                    777: 
                    778: void
                    779: upput( p ) register NODE *p; 
                    780: {
                    781:        /* output the address of the second word in the
                    782:           pair pointed to by p (for LONGs)*/
                    783:        CONSZ save;
                    784:        int r;
                    785: 
                    786:        if( p->in.op == FLD ){
                    787:                p = p->in.left;
                    788:        }
                    789: 
                    790:        save = p->tn.lval;
                    791:        switch( p->in.op ){
                    792: 
                    793:        case NAME:
                    794:                p->tn.lval += SZINT/SZCHAR;
                    795:                acon( p );
                    796:                break;
                    797: 
                    798:        case FCON:
                    799:                fcon( p, F_loworder );
                    800:                break;
                    801: 
                    802:        case ICON:
                    803:                /* addressable value of the constant */
                    804:                p->tn.lval &= BITMASK(SZINT);
                    805:                putchar('#');
                    806:                acon( p );
                    807:                break;
                    808: 
                    809:        case REG:
                    810:                r = p->tn.rval+1;
                    811:                if (r >= FP0) {
                    812:                        cerror("illegal floating register pair");
                    813:                }
                    814:                print_str(rnames[r] );
                    815:                markused(r);
                    816:                break;
                    817: 
                    818:        case OREG:
                    819:                p->tn.lval += SZINT/SZCHAR;
                    820:                if( R2UPK2(p->tn.rval) == A6 ){  /* in the argument region */
                    821:                    if( p->in.name[0] != '\0' ) werror( "bad arg temp" );
                    822:                } 
                    823: #ifdef FREETEMP
                    824:                else if( R2UPK2(p->tn.rval) == SP ){  /* in the temp region */
                    825:                    if( p->in.name[0] != '\0' ) werror( "bad arg temp" );
                    826:                    printf( "sp@(LT%d+0x%x)", ftnno, toff+p->tn.lval);
                    827:                    p->tn.lval = save;
                    828:                    return;
                    829:                } 
                    830: #endif FREETEMP
                    831:                oregput(p);
                    832:                break;
                    833: 
                    834:        case UNARY MUL:
                    835:                if (p->in.left->in.op==INCR){
                    836:                    /* rewrite a-la adrput */
                    837:                    NODE *q, *l; int i;
                    838:                    l = p->in.left;
                    839:                    q = l->in.left;
                    840:                    p->in.op = OREG;
                    841:                    p->in.rall = q->in.rall;
                    842:                    p->tn.lval = q->tn.lval;
                    843:                    p->tn.rval = q->tn.rval;
                    844: #ifndef FLEXNAMES
                    845:                    for( i=0; i<NCHNAM; i++ )
                    846:                            p->in.name[i] = q->in.name[i];
                    847: #else
                    848:                    p->in.name = q->in.name;
                    849: #endif
                    850:                    adrput( p );
                    851:                    putchar('+');
                    852:                    p->tn.lval -= l->in.right->tn.lval;
                    853:                    tfree( l );
                    854:                } else if ( tshape(p, STARNM) ) {
                    855:                    adrput( p->in.left );
                    856:                    print_str("@(4)");
                    857:                } else {
                    858:                    /*  p->in.left->in.op==ASG MINUS */
                    859:                    /* just put and let adrput rewrite -- VERY carefully */
                    860:                    adrput( p->in.left->in.left );
                    861:                    print_str( "@-");
                    862:                }
                    863:                break;
                    864: 
                    865:        default:
                    866:                cerror( "illegal upper address" );
                    867:                break;
                    868: 
                    869:                }
                    870:        p->tn.lval = save;
                    871: }
                    872: 
                    873: void
                    874: adrput( p ) register NODE *p; 
                    875: {
                    876:        /* the 68k code saves lval and restores after the switch */
                    877:        register int r;
                    878:        /* output an address, with offsets, from p */
                    879: 
                    880:        if( p->in.op == FLD ){
                    881:            p = p->in.left;
                    882:        }
                    883:        switch( p->in.op ){
                    884: 
                    885:        case NAME:
                    886:                acon( p );
                    887:                return;
                    888: 
                    889:        case FCON:
                    890:                /*
                    891:                 * put out floating constant in hex.
                    892:                 * Do not use in coprocessor instructions;
                    893:                 * use floatimmed(p) instead.
                    894:                 */
                    895:                if (p->in.type == FLOAT) {
                    896:                        putchar('#');
                    897:                        fcon( p, F_hex );
                    898:                } else {
                    899:                        fcon( p, F_highorder );
                    900:                }
                    901:                return;
                    902: 
                    903:        case ICON:
                    904:                /* addressable value of the constant */
                    905:                putchar('#');
                    906:                acon( p );
                    907:                return;
                    908: 
                    909:        case REG:
                    910:                r = p->tn.rval;
                    911:                print_str(rnames[r] );
                    912:                markused(r);
                    913:                return;
                    914: 
                    915:        case OREG:
                    916:                if( R2UPK2(p->tn.rval) == A6 ){  /* in the argument region */
                    917:                    if( p->in.name[0] != '\0' ) werror( "bad arg temp" );
                    918:                } 
                    919: #ifdef FREETEMP
                    920:                else if( R2UPK2(p->tn.rval) == SP ){  /* in the temp region */
                    921:                    if( p->in.name[0] != '\0' ) werror( "bad arg temp" );
                    922:                    printf( "sp@(LT%d+%d)", ftnno, toff+p->tn.lval);
                    923:                    return;
                    924:                }
                    925: #endif FREETEMP
                    926:                oregput(p);
                    927:                break;
                    928: 
                    929:        case UNARY MUL:
                    930:                /* STARNM or STARREG found */
                    931:                if( tshape(p, STARNM) ) {
                    932:                        adrput( p->in.left);
                    933:                        putchar('@');
                    934:                }
                    935:                else {  /* STARREG - really auto inc or dec */
                    936:                        /* turn into OREG so replacement node will
                    937:                           reflect the value of the expression */
                    938:                        register i;
                    939:                        register NODE *q, *l;
                    940: 
                    941:                        l = p->in.left;
                    942:                        q = l->in.left;
                    943:                        if (p->in.type==DOUBLE )
                    944:                            if (l->in.op==INCR){
                    945:                                /* just do it and let upput rewrite */
                    946:                                adrput( q );
                    947:                                print_str( "@+");
                    948:                                return;
                    949:                            }
                    950:                            /* else fall through and we rewrite -- VERY carefully */
                    951:                        p->in.op = OREG;
                    952:                        p->in.rall = q->in.rall;
                    953:                        p->tn.lval = q->tn.lval;
                    954:                        p->tn.rval = q->tn.rval;
                    955: #ifndef FLEXNAMES
                    956:                        for( i=0; i<NCHNAM; i++ )
                    957:                                p->in.name[i] = q->in.name[i];
                    958: #else
                    959:                        p->in.name = q->in.name;
                    960: #endif
                    961:                        if( l->in.op == INCR ) {
                    962:                                adrput( p );
                    963:                                putchar('+');
                    964:                                p->tn.lval -= l->in.right->tn.lval;
                    965:                        } else {        
                    966:                                /* l->in.op == ASG MINUS */
                    967:                                adrput( p );
                    968:                                putchar('-');
                    969:                        }
                    970:                        tfree( l );
                    971:                }
                    972:                return;
                    973: 
                    974:        case SCONV:
                    975:                adrput(p->in.left);     /* kludge for SFLOAT_SRCE */
                    976:                break;
                    977: 
                    978:        default:
                    979:                cerror( "illegal address" );
                    980:                return;
                    981: 
                    982:        }
                    983: 
                    984: }
                    985: 
                    986: acon( p ) register NODE *p; 
                    987: { /* print out a constant */
                    988: 
                    989:        if( p->in.name[0] == '\0' ){
                    990:                print_x(p->tn.lval);
                    991:                }
                    992:        else if( p->tn.lval == 0 ) {
                    993: #ifndef FLEXNAMES
                    994:                printf( "%.8s", p->in.name );
                    995: #else
                    996:                print_str(p->in.name );
                    997: #endif
                    998:                }
                    999:        else {
                   1000: #ifndef FLEXNAMES
                   1001:                printf( "%.8s+", p->in.name );
                   1002: #else
                   1003:                print_str(p->in.name ); putchar('+');
                   1004: #endif
                   1005:                print_x(p->tn.lval );
                   1006:                }
                   1007: }
                   1008: 
                   1009: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
                   1010: 
                   1011: /*
                   1012:  * fcon(p, form):  output a floating point constant in one of several forms
                   1013:  */
                   1014: 
                   1015: static int fgetlab();
                   1016: 
                   1017: static char floatfmt[] = "0r%.9e";
                   1018: static char doublefmt[] = "0r%.17e";
                   1019: 
                   1020: static void
                   1021: fcon( p, form )
                   1022:        register NODE *p;
                   1023:        Floatform form;
                   1024: {
                   1025:        float x;
                   1026:        long *lp;
                   1027: 
                   1028:        switch(form) {
                   1029:        case F_highorder:
                   1030:                /*
                   1031:                 * put out a reference to the highorder word of a
                   1032:                 * double constant from the pool
                   1033:                 */
                   1034:                printf("L%d", fgetlab(p));
                   1035:                return;
                   1036:        case F_loworder:
                   1037:                /*
                   1038:                 * put out a reference to the loworder word of a
                   1039:                 * double constant from the pool
                   1040:                 */
                   1041:                printf("L%d+4", fgetlab(p));
                   1042:                return;
                   1043:        case F_eformat:
                   1044:                /*
                   1045:                 * put out a constant in e-floating point format;
                   1046:                 * for coprocessor instructions.
                   1047:                 */
                   1048:                if (p->in.type == FLOAT) {
                   1049:                        printf(floatfmt, p->fpn.dval);
                   1050:                } else {
                   1051:                        printf(doublefmt, p->fpn.dval);
                   1052:                }
                   1053:                return;
                   1054:        case F_hex:
                   1055:                /*
                   1056:                 * put out the constant as one or two hex words;
                   1057:                 * for initialization.
                   1058:                 */
                   1059:                if (p->in.type == FLOAT) {
                   1060:                        float x = p->fpn.dval;
                   1061:                        lp = (long*)&x;
                   1062:                        printf("0x%x", lp[0]);
                   1063:                } else {
                   1064:                        lp = (long*)&p->fpn.dval;
                   1065:                        printf("0x%x,0x%x", lp[0], lp[1]);
                   1066:                }
                   1067:                return;
                   1068:        }
                   1069: }
                   1070: 
                   1071: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
                   1072: 
                   1073: /*
                   1074:  * floating point constant pool -- a data structure that
                   1075:  * associates floating point constants with labels
                   1076:  */
                   1077: 
                   1078: struct floatcon {
                   1079:        int conlab;
                   1080:        TWORD contype;
                   1081:        double conval;
                   1082:        struct floatcon *left, *right;
                   1083: };
                   1084: 
                   1085: static struct floatcon *fconpool;      /* the search tree */
                   1086: static struct floatcon *newfloatcon(); /* floatcon storage allocator */
                   1087: static int fconlookup();               /* search routine */
                   1088: 
                   1089: /*
                   1090:  * search for, and create if necessary,
                   1091:  * a label in the floating point constant pool
                   1092:  */
                   1093: 
                   1094: static int
                   1095: fgetlab(p)
                   1096:        NODE *p;
                   1097: {
                   1098:        return(fconlookup(&fconpool, p));
                   1099: }
                   1100: 
                   1101: static int
                   1102: fconlookup(fpp, p)
                   1103:        struct floatcon **fpp;
                   1104:        NODE *p;
                   1105: {
                   1106:        struct floatcon *fp = *fpp;
                   1107:        if (fp == NULL) {
                   1108:                *fpp = fp = newfloatcon();
                   1109:                fp->conval = p->fpn.dval;
                   1110:                fp->contype = p->fpn.type;
                   1111:                fp->conlab = getlab();
                   1112:                fp->left = NULL;
                   1113:                fp->right = NULL;
                   1114:                return(fp->conlab);
                   1115:        } else if (fp->conval == p->fpn.dval) {
                   1116:                return(fp->conlab);
                   1117:        } else if (fp->conval < p->fpn.dval) {
                   1118:                return(fconlookup(&fp->left, p));
                   1119:        } else {
                   1120:                return(fconlookup(&fp->right,p));
                   1121:        }
                   1122: }
                   1123: 
                   1124: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
                   1125: 
                   1126: /*
                   1127:  * storage allocation for the floating point constant pool
                   1128:  */
                   1129: 
                   1130: #define FCONSEGSIZ 256
                   1131: struct fconseg {
                   1132:        struct fconseg  *nextseg;
                   1133:        struct floatcon *nextcon;
                   1134:        struct floatcon storage[FCONSEGSIZ];
                   1135: };
                   1136: 
                   1137: static struct fconseg *curseg = NULL;
                   1138: 
                   1139: /*
                   1140:  * allocate storage for a
                   1141:  * labeled floating point constant
                   1142:  */
                   1143: static struct floatcon *
                   1144: newfloatcon()
                   1145: {
                   1146:        struct fconseg *newseg;
                   1147: 
                   1148:        if (curseg == NULL
                   1149:            || curseg->nextcon == curseg->storage+FCONSEGSIZ) {
                   1150:                newseg = (struct fconseg*)malloc(sizeof(struct fconseg));
                   1151:                newseg->nextseg = curseg;
                   1152:                curseg = newseg;
                   1153:                curseg->nextcon = curseg->storage;
                   1154:        }
                   1155:        return(curseg->nextcon++);
                   1156: }
                   1157: 
                   1158: /*
                   1159:  * emit the floating point constant
                   1160:  * pool to the output stream
                   1161:  */
                   1162: static void
                   1163: dumpfcons()
                   1164: {
                   1165:        register struct floatcon *fp,*nextfree;
                   1166:        struct fconseg *segp, *temp;
                   1167:        long *lp;
                   1168: 
                   1169:        segp = curseg;
                   1170:        while(segp != NULL) {
                   1171:                nextfree = segp->nextcon;
                   1172:                for (fp = segp->storage; fp < nextfree; fp++) {
                   1173:                        printf("L%d:    .long   ", fp->conlab);
                   1174:                        if (fp->contype == FLOAT) {
                   1175:                                float x = fp->conval;
                   1176:                                lp = (long*)&x;
                   1177:                                printf("0x%lx", lp[0]);
                   1178:                        } else {
                   1179:                                lp = (long*)&fp->conval;
                   1180:                                printf("0x%lx,0x%lx", lp[0], lp[1]);
                   1181:                        }
                   1182:                        putchar('\n');
                   1183:                }
                   1184:                temp = segp->nextseg;
                   1185:                free(segp);
                   1186:                segp = temp;
                   1187:        }
                   1188:        curseg = NULL;
                   1189:        fconpool = NULL;
                   1190: }
                   1191: 
                   1192: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
                   1193: 
                   1194: genscall( p, cookie ) register NODE *p; 
                   1195: {
                   1196:        /* structure valued call */
                   1197:        return( gencall( p, cookie ) );
                   1198: }
                   1199: 
                   1200: gencall( p, cookie ) register NODE *p;
                   1201: {
                   1202:        /* generate the call given by p */
                   1203:        register args;
                   1204:        register m;
                   1205: 
                   1206:        if( p->in.right ) args = argsize( p->in.right );
                   1207:        else args = 0;
                   1208: 
                   1209:        if( p->in.right ){ /* generate args */
                   1210:                int residue = args % (SZLONG/SZCHAR);
                   1211:                if (residue) {
                   1212:                        /*
                   1213:                         * pad the argument list out to an
                   1214:                         * even number of longwords.  This is
                   1215:                         * the wrong way to do it, but doing
                   1216:                         * it right isn't backwards compatible.
                   1217:                         */
                   1218:                        printf("        subqw   #0x%x,sp\n", residue);
                   1219:                }
                   1220:                genargs( p->in.right );
                   1221:        }
                   1222: 
                   1223:        if( !shltype( p->in.left->in.op, p->in.left ) ) {
                   1224:                order( p->in.left, INBREG|SOREG );
                   1225:        }
                   1226: 
                   1227:        p->in.op = UNARY CALL;
                   1228:        m = match( p, INTAREG|INTBREG );
                   1229:        popargs( args );
                   1230:        return(m != MDONE);
                   1231: }
                   1232: 
                   1233: popargs( size ) register size; 
                   1234: {
                   1235:        /* pop arguments from stack */
                   1236: 
                   1237:        if (size==0) return;
                   1238:        /*
                   1239:         * round size up to a multiple of sizeof(long),
                   1240:         * to compensate for the hack in gencall() above.
                   1241:         */
                   1242:        SETOFF(size, (SZLONG/SZCHAR));
                   1243:        toff -= size;
                   1244:        /* huh? if( toff == 0 && size >= 2 ) size -= 2; */
                   1245:        if (size <=8 )
                   1246:                printf( "       addqw   #0x%x,sp\n", size);
                   1247:        else if (size <(1<<15))
                   1248:                printf( "       lea     sp@(0x%x),sp\n", size);
                   1249:        else
                   1250:                printf( "       addl    #0x%x,sp\n", size);
                   1251: }
                   1252: 
                   1253: 
                   1254: nextcook( p, cookie ) 
                   1255:        NODE *p; 
                   1256:        register cookie;
                   1257: {
                   1258:        /* we have failed to match p with cookie; try another */
                   1259:        if ( cookie == FORREW ) return( 0 );  /* hopeless! */
                   1260:        if ( cookie & (INCREG|INTCREG) ) return (INTAREG);
                   1261:        if ( !(cookie&(INTAREG|INTBREG|INTCREG)) )
                   1262:                return( INTAREG|INTBREG|INTCREG );
                   1263:        if ( !(cookie&INTEMP) && asgop(p->in.op) ) 
                   1264:                return( INTEMP|INAREG|INTAREG|INTBREG|INBREG);
                   1265:        if ( !(cookie&(INTAREG|INAREG)) && p->in.op == CHK )
                   1266:                return(INTAREG|INAREG);
                   1267:        return ( FORREW );
                   1268: }
                   1269: 
                   1270: lastchance( p, cook ) NODE *p; 
                   1271: {
                   1272:        /* forget it! */
                   1273:        return(0);
                   1274: }
                   1275: 
                   1276: 
                   1277: NODE * addroreg(l)
                   1278: /*
                   1279:  * OREG was built in clocal()
                   1280:  * for an auto or formal parameter
                   1281:  * now its address is being taken
                   1282:  * local code must unwind it
                   1283:  * back to PLUS/MINUS REG ICON
                   1284:  * according to local conventions
                   1285:  */
                   1286: {
                   1287:        cerror("address of OREG taken");
                   1288: }
                   1289: 
                   1290: 
                   1291: 
                   1292: # ifndef ONEPASS
                   1293: main( argc, argv ) char *argv[]; 
                   1294: {
                   1295:        int v;
                   1296:        if ( strcmp(argv[0],pcname) == 0 )
                   1297:                pascal = 1;
                   1298:        v = mainp2( argc, argv );
                   1299:        floatnote();
                   1300:        exit( v );
                   1301: }
                   1302: # endif
                   1303: 
                   1304: /* return 1 if node is a SCONV from short to int */
                   1305: isconv( p, t1, t2 )
                   1306:     register NODE *p;
                   1307:     TWORD t1, t2;
                   1308: {
                   1309:     register v;
                   1310:     if ( p->in.op==SCONV && (p->in.type==INT || p->in.type==UNSIGNED) && 
                   1311:        ((v=p->in.left->in.type)==t1 || v == t2))
                   1312:              return( 1 );
                   1313:        return( 0 );
                   1314: }
                   1315: 
                   1316: 
                   1317: 
                   1318: myreader(p) register NODE *p; 
                   1319: {
                   1320: #ifdef FORT
                   1321:        void unoptim2();
                   1322:        if (!pascal) {
                   1323:                unoptim2(p);
                   1324:        }
                   1325: #endif FORT
                   1326:        optim2(p);
                   1327:        canon( p );             /* expands r-vals for fields */
                   1328:        toff = 0;  /* stack offset swindle */
                   1329: #ifdef FREETEMP
                   1330:        tmpoff = 0; /* we number temp regsters differently here */
                   1331: #endif
                   1332: }
                   1333: 
                   1334: 
                   1335: special( p, shape ) register NODE *p; 
                   1336: {
                   1337:        /* special shape matching routine */
                   1338: 
                   1339:        switch (shape){
                   1340:        case SPEC_FLD:
                   1341:            /* do-it-yourself multi-level matching */
                   1342:            if (tshape(p,SFLD))
                   1343:                switch( p->in.left->tn.op){
                   1344:                case OREG:
                   1345:                        /* if (R2TEST(p->in.left->tn.rval)) return 0; */
                   1346:                case REG:
                   1347:                case ICON:
                   1348:                case NAME:
                   1349:                        return(1);
                   1350:                }
                   1351:                return 0;
                   1352: 
                   1353:        case SPEC_FLT:
                   1354:            /* depends on phase of moon */
                   1355:            if (usesky)
                   1356:                return tshape(p,SCON|SAREG|STAREG|SBREG|SOREG|SNAME|STARREG);
                   1357:            else
                   1358:                return tshape(p,SAREG|STAREG) && (p->tn.rval==D0 || p->tn.rval==D1);
                   1359:        case SPEC_DFLT:
                   1360:            /* likewise */
                   1361:            if (usesky)
                   1362:                return tshape(p,SCON|SAREG|STAREG|SBREG|SOREG|SNAME|STARREG);
                   1363:            else
                   1364:                return tshape(p,SCON|                   SOREG|SNAME|STARREG);
                   1365: 
                   1366:        case SFLOAT_SRCE:
                   1367:            /* source operand of 68881 floating point instruction */
                   1368:            if (p->in.op == SCONV) {
                   1369:                /*
                   1370:                 * the 68881 converts signed integral types into
                   1371:                 * (extended) floating point format
                   1372:                 */
                   1373:                p = p->in.left;
                   1374:                switch(p->in.type) {
                   1375:                case CHAR:
                   1376:                case SHORT:
                   1377:                case INT:
                   1378:                case LONG:
                   1379:                case FLOAT:
                   1380:                    /* d-registers, constants, and memory are all ok */
                   1381:                    return tshape(p,
                   1382:                        SCON|SCREG|STCREG|SAREG|STAREG|SOREG|SNAME|STARNM|STARREG);
                   1383:                case DOUBLE:
                   1384:                    /* can't deal with register pairs */
                   1385:                    return tshape(p,
                   1386:                        SCON|SCREG|STCREG|SOREG|SNAME|STARNM|STARREG);
                   1387:                default:
                   1388:                    return(0);
                   1389:                }
                   1390:            }
                   1391:            if (p->in.type == FLOAT) {
                   1392:                /* d-regs, f-registers, or memory */
                   1393:                return tshape(p,
                   1394:                    SCON|SCREG|STCREG|SAREG|STAREG|SOREG|SNAME|STARNM|STARREG);
                   1395:            }
                   1396:            /* type == DOUBLE: f-registers or memory only */
                   1397:            return tshape(p, SCON|SCREG|STCREG|SOREG|SNAME|STARNM|STARREG);
                   1398: 
                   1399:        case SPEC_PVT:
                   1400:            /* right subtree of x + y*z ; an idiom from matrix computations */
                   1401:            if (!usesky) return 0;
                   1402:            if (p->in.op != MUL) return 0;
                   1403:            if (tshape(p->in.left,SCON|SAREG|STAREG|SBREG|SOREG|SNAME|STARREG)){
                   1404:                return tshape(p->in.right,
                   1405:                    SCON|SAREG|STAREG|SBREG|SOREG|SNAME|STARREG);
                   1406:            }
                   1407:            return 0;
                   1408: 
                   1409:        case SSOREG:
                   1410:            /* someday soon, this will be useful */
                   1411:            return ( p->in.op == OREG && !R2TEST(p->tn.rval) );
                   1412: 
                   1413:        case SBASE:
                   1414:            /* half of a double-oreg */
                   1415:            return ( p->in.op == PLUS
                   1416:                && p->in.left->in.op == REG && isbreg(p->in.left->tn.rval)
                   1417:                && (p=p->in.right)->in.op == ICON && p->tn.name[0] == '\0'
                   1418:                && p->tn.lval >= -127 && p->tn.lval <= 127 );
                   1419: 
                   1420:        case SXREG:
                   1421:            /* the other half */
                   1422:            if ( p->in.op==SCONV
                   1423:                && (p->in.type == INT || p->in.type == UNSIGNED)
                   1424:                && p->in.left->in.type == SHORT )
                   1425:                      p = p->in.left;
                   1426:            return ( p->in.op == REG );
                   1427: 
                   1428:        case SNONPOW2:
                   1429:            /*
                   1430:             * constant, NOT a power of 2.  This is a kludge to enable
                   1431:             * us to match a template for ASG MOD on the 68020.  The
                   1432:             * semantics of the DIVSLL instruction make it impossible
                   1433:             * to return a remainder in the lhs of <reg> %= <ea>, unless
                   1434:             * an extra instruction is generated. Returning the result
                   1435:             * in RESC1 makes the extra instruction unnecessary.
                   1436:             */
                   1437:            return( p->in.op == ICON && (p->tn.lval & p->tn.lval-1) );
                   1438: 
                   1439:        case SAUTOINC:
                   1440:            return( p->in.op == UNARY MUL
                   1441:                && p->in.left->in.op == INCR
                   1442:                && shumul(p->in.left) == STARREG );
                   1443: 
                   1444:        /*
                   1445:         *  CHK bounds pair with constant lower bound of 0
                   1446:         */
                   1447:        case SZEROLB:
                   1448:            return( p->in.op == CM
                   1449:                && p->in.left->in.op == ICON
                   1450:                && p->in.left->tn.name == NULL
                   1451:                && p->in.left->tn.lval == 0 );
                   1452: 
                   1453:        case SFZERO:
                   1454:            return( p->in.op == FCON && p->fpn.dval == 0.0 );
                   1455: 
                   1456:        }
                   1457: 
                   1458:        if(p->tn.op != ICON || p->in.name[0] != '\0') return (0);
                   1459:        switch( shape ) {
                   1460:        case SCCON:
                   1461:                return( p->tn.lval>= -128 && p->tn.lval <=127 );
                   1462:        case SICON:
                   1463:                return( p->tn.lval>= 0 && p->tn.lval <=32767 );
                   1464:        case SSCON:
                   1465:                return( p->tn.lval>= -32768 && p->tn.lval <=32767 );
                   1466:        case S8CON:
                   1467:                return( p->tn.lval>= 1 && p->tn.lval <=8 );
                   1468:        default:
                   1469:                cerror( "bad special shape" );
                   1470:        }
                   1471: 
                   1472:        return( 0 );
                   1473: }
                   1474: 
                   1475: # ifdef MULTILEVEL
                   1476: # include "mldec.h"
                   1477: 
                   1478: struct ml_node mltree[] ={
                   1479: 
                   1480: DEFINCDEC,     INCR,   0,
                   1481:        INCR,   SANY,   TANY,
                   1482:                OPANY,  SAREG|STAREG,   TANY,
                   1483:                OPANY,  SCON,   TANY,
                   1484: 
                   1485: DEFINCDEC,     ASG MINUS,      0,
                   1486:        ASG MINUS,      SANY,   TANY,
                   1487:                REG,    SANY,   TANY,
                   1488:                ICON,   SANY,   TANY,
                   1489: 
                   1490: TSOREG,        1,      0,
                   1491:        UNARY MUL,      SANY,   TANY,
                   1492:                REG,    SANY,   TANY,
                   1493: 
                   1494: TSOREG,        2,      0,
                   1495:        UNARY MUL,      SANY,   TANY,
                   1496:                PLUS,   SANY,   TANY,
                   1497:                        REG,    SANY,   TANY,
                   1498:                        ICON,   SANY,   TCHAR|TUCHAR|TSHORT|TUSHORT|TINT|TUNSIGNED|TPOINT,
                   1499: 
                   1500: TSOREG,        2,      0,
                   1501:        UNARY MUL,      SANY,   TANY,
                   1502:                MINUS,  SANY,   TANY,
                   1503:                        REG,    SANY,   TANY,
                   1504:                        ICON,   SANY,   TCHAR|TUCHAR|TSHORT|TUSHORT|TINT|TUNSIGNED|TPOINT,
                   1505: 0,0,0};
                   1506: # endif
                   1507: 
                   1508: #ifdef FREETEMP
                   1509: extern unsigned offsz;
                   1510: 
                   1511: freetemp( k )
                   1512: { 
                   1513:     /* allocate k integers worth of temp space */
                   1514:     /* we also make the convention that, if the number of words is more than 1,
                   1515:     /* it must be aligned for storing doubles... */
                   1516:     /* allocate temps forwards from sp+(saved registers) */
                   1517: 
                   1518:        int t;
                   1519: 
                   1520:        if( k>1 ){
                   1521:                SETOFF( tmpoff, ALDOUBLE );
                   1522:        }
                   1523:        t = tmpoff;
                   1524:        tmpoff += k*SZINT;
                   1525:        if( tmpoff >= offsz )
                   1526:                cerror( "stack overflow" );
                   1527:        if( tmpoff > maxtemp ) maxtemp = tmpoff ;
                   1528:        return(t);
                   1529: 
                   1530: }
                   1531: #endif FREETEMP
                   1532: 
                   1533: #ifdef FORT
                   1534: void
                   1535: unoptim2( p ) register NODE *p;
                   1536: {
                   1537:     /* FORTRAN thinks we can do double operations on float operands */
                   1538:     NODE * double_conv();
                   1539:     switch( optype(p->in.op)){
                   1540:     case BITYPE:
                   1541:        unoptim2(p->in.left);
                   1542:        unoptim2(p->in.right);
                   1543:        if (p->in.type == DOUBLE){
                   1544:            switch (p->in.op) {
                   1545:            case QUEST:
                   1546:            case CM:
                   1547:            case COMOP:
                   1548:            case CALL:
                   1549:                    return;
                   1550:            }
                   1551:            if (p->in.right->in.type != DOUBLE)
                   1552:                p->in.right = double_conv(p->in.right);
                   1553:            if (p->in.left->in.type != DOUBLE)
                   1554:                p->in.left = double_conv(p->in.left);
                   1555:            return;
                   1556:        }
                   1557:        if ( logop(p->in.op) ){
                   1558:            if (p->in.left->in.type==DOUBLE && p->in.right->in.type != DOUBLE)
                   1559:                p->in.right = double_conv(p->in.right);
                   1560:            if (p->in.right->in.type==DOUBLE && p->in.left->in.type != DOUBLE)
                   1561:                p->in.left = double_conv(p->in.left);
                   1562:        }
                   1563:        return;
                   1564:     case UTYPE:
                   1565:        unoptim2(p->in.left);
                   1566:        if (p->in.type == DOUBLE ){
                   1567:            switch( p->in.op ){
                   1568:            case UNARY MUL:
                   1569:            case UNARY CALL:
                   1570:            case SCONV:
                   1571:                return;
                   1572:            }
                   1573:            if (p->in.left->in.type != DOUBLE)
                   1574:                p->in.left = double_conv(p->in.left);
                   1575:        }
                   1576:        return;
                   1577:     case LTYPE: return;
                   1578:     }
                   1579: }
                   1580: #endif FORT
                   1581: 

unix.superglobalmegacorp.com

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