Annotation of researchv9/cmd/sun/pcc/util2.c, revision 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.