Annotation of researchv9/cmd/sun/pcc/save/code.c, revision 1.1

1.1     ! root        1: #ifndef lint
        !             2: static char sccsid[] = "@(#)code.c 1.1 86/02/03 SMI";
        !             3: #endif
        !             4: 
        !             5: 
        !             6: # include "cpass1.h"
        !             7: # include <sys/types.h>
        !             8: 
        !             9: # include <a.out.h>
        !            10: # include <stab.h>
        !            11: 
        !            12: #ifndef VAX
        !            13: extern char *rnames[];
        !            14: #endif
        !            15: 
        !            16: #ifndef ONEPASS
        !            17: int usedregs;
        !            18: int usedfpregs;
        !            19: #endif !ONEPASS
        !            20: 
        !            21: int proflg = 0;        /* are we generating profiling code? */
        !            22: int strftn = 0;  /* is the current function one which returns a value */
        !            23: int fltfun = 0; /* is function float or double? */
        !            24: int optimize = 0; /* is optimization enabled? If so, no SLINEs for you */
        !            25: #ifdef STACKPROBE
        !            26: int noprobe= 1; /* are we not generating 68000 stack probes? */
        !            27: #endif
        !            28: int gdebug;
        !            29: extern int oldway;
        !            30: int fdefflag;  /* are we within a function definition ? */
        !            31: char NULLNAME[8];
        !            32: int labelno;
        !            33: 
        !            34: branch( n )
        !            35: {
        !            36:        /* output a branch to label n */
        !            37:        /* exception is an ordinary function branching to retlab: then, return */
        !            38:        if( n == retlab && !strftn ){
        !            39: #ifdef VAX
        !            40:                printf( "       ret\n" );
        !            41: #else
        !            42:                printf( "       jra     LE%d\n", ftnno );
        !            43: #endif
        !            44:                }
        !            45:        else 
        !            46: #ifdef VAX
        !            47:                printf( "       jbr     L%d\n", n );
        !            48: #else
        !            49:                printf("        jra     L%d\n", n );
        !            50: #endif
        !            51: }
        !            52: 
        !            53: int lastloc = { -1 };
        !            54: 
        !            55: #ifdef VAX
        !            56: short log2tab[] = {0, 0, 1, 2, 2, 3, 3, 3, 3};
        !            57: #define LOG2SZ 9
        !            58: #endif
        !            59: 
        !            60: defalign(n) 
        !            61: {
        !            62:        /* cause the alignment to become a multiple of n */
        !            63: #ifdef VAX
        !            64:        n /= SZCHAR;
        !            65:        if( lastloc != PROG && n > 1 ) printf( "        .align  %d\n", n >= 0 && n < LOG2SZ ? log2tab[n] : 0 );
        !            66: #else
        !            67:        if ( lastloc != PROG && n > 1 ) printf("        .even\n");
        !            68: #endif
        !            69: }
        !            70: 
        !            71: locctr( l )
        !            72: {
        !            73:        register temp;
        !            74:        /* l is PROG, ADATA, DATA, STRNG, ISTRNG, or STAB */
        !            75: 
        !            76:        if( l == lastloc ) return(l);
        !            77:        temp = lastloc;
        !            78:        lastloc = l;
        !            79:        switch( l ){
        !            80: 
        !            81:        case PROG:
        !            82:                printf( "       .text\n" );
        !            83:                if (gdebug && !oldway)
        !            84:                        psline(lineno);
        !            85:                break;
        !            86: 
        !            87:        case DATA:
        !            88:        case ADATA:
        !            89:                if (temp != DATA && temp != ADATA)
        !            90:                        printf( "       .data\n" );
        !            91:                break;
        !            92: 
        !            93:        /* The following levels of .data statements will be problems if
        !            94:           there is ever any relocation required. */
        !            95:        case STRNG:
        !            96: #ifdef VAX
        !            97:                printf( "       .data   1\n" );
        !            98: #else
        !            99:                printf( "       .data1\n" );
        !           100: #endif
        !           101:                break;
        !           102: 
        !           103:        case ISTRNG:
        !           104: #ifdef VAX
        !           105:                printf( "       .data   2\n" );
        !           106: #else
        !           107:                printf( "       .data2\n" );
        !           108: #endif
        !           109:                break;
        !           110: 
        !           111:        case STAB:
        !           112:                printf( "       .stab\n" );
        !           113:                break;
        !           114: 
        !           115:        default:
        !           116:                cerror( "illegal location counter" );
        !           117:                }
        !           118: 
        !           119:        return( temp );
        !           120: }
        !           121: 
        !           122: deflab( n )
        !           123: {
        !           124:        /* output something to define the current position as label n */
        !           125:        printf( "L%d:\n", n );
        !           126: }
        !           127: 
        !           128: int crslab = 10;
        !           129: 
        !           130: getlab()
        !           131: {
        !           132:        /* return a number usable for a label */
        !           133:        return( ++crslab );
        !           134: }
        !           135: 
        !           136: 
        !           137: #ifdef VAX
        !           138: int ent_mask[] = {
        !           139:        0,0,0,0,0, 0xfc0, 0xf80, 0xf00, 0xe00, 0xc00, 0x800, 0};
        !           140: 
        !           141: int reg_use = 11;
        !           142: #else
        !           143: extern int regsused;
        !           144: #endif
        !           145: 
        !           146: efcode()
        !           147: {
        !           148:        /* code for the end of a function */
        !           149: 
        !           150: #ifdef VAX
        !           151:        if( strftn ){  /* copy output (in R2) to caller */
        !           152:                register NODE *l, *r;
        !           153:                register struct symtab *p;
        !           154:                register TWORD t;
        !           155:                register int j;
        !           156:                int i;
        !           157: 
        !           158:                p = STP(curftn);
        !           159:                t = p->stype;
        !           160:                t = DECREF(t);
        !           161: 
        !           162:                deflab( retlab );
        !           163: 
        !           164:                i = getlab();   /* label for return area */
        !           165: #ifndef LCOMM
        !           166:                printf("        .data\n" );
        !           167:                printf("        .align  2\n" );
        !           168:                printf("L%d:    .space  %d\n", i, tsize(t, p->dimoff, p->sizoff)/SZCHAR );
        !           169:                printf("        .text\n" );
        !           170: #else
        !           171:                { int sz = tsize(t, p->dimoff, p->sizoff) / SZCHAR;
        !           172:                if (sz % sizeof (int))
        !           173:                        sz += sizeof (int) - (sz % sizeof (int));
        !           174:                printf("        .lcomm  L%d,%d\n", i, sz);
        !           175:                }
        !           176: #endif
        !           177:                psline(lineno);
        !           178:                printf("        movab   L%d,r1\n", i);
        !           179: 
        !           180:                reached = 1;
        !           181:                l = block( REG, NIL, NIL, PTR|t, p->dimoff, p->sizoff );
        !           182:                l->tn.rval = 1;  /* R1 */
        !           183:                l->tn.lval = 0;  /* no offset */
        !           184:                r = block( REG, NIL, NIL, PTR|t, p->dimoff, p->sizoff );
        !           185:                r->tn.rval = 0;  /* R0 */
        !           186:                r->tn.lval = 0;
        !           187:                l = buildtree( UNARY MUL, l, NIL );
        !           188:                r = buildtree( UNARY MUL, r, NIL );
        !           189:                l = buildtree( ASSIGN, l, r );
        !           190:                l->in.op = FREE;
        !           191:                ecomp( l->in.left );
        !           192:                printf( "       movab   L%d,r0\n", i );
        !           193:                /* turn off strftn flag, so return sequence will be generated */
        !           194:                strftn = 0;
        !           195:                }
        !           196:        branch( retlab );
        !           197: #ifndef VMS
        !           198:        printf( "       .set    L%d,0x%x\n", ftnno, ent_mask[reg_use] );
        !           199: #else
        !           200:        printf( "       .set    L%d,%d  # Hex = 0x%x\n", ftnno, 0x3c| ent_mask[reg_use], ent_mask[reg_use]  );
        !           201:        /* KLS kludge, under VMS if you use regs 2-5, you must save them. */
        !           202: #endif
        !           203:        reg_use = 11;
        !           204:        p2bend();
        !           205:        fdefflag = 0;
        !           206: #else
        !           207: /* 68k code */
        !           208: /* NOTE: We still have to add FTN and stab support here */
        !           209:        if( strftn ){  /* copy output (in r0) to caller */
        !           210:                register struct symtab *p;
        !           211:                register int stlab;
        !           212:                register int count;
        !           213:                int size;
        !           214: 
        !           215:                p = STP(curftn);
        !           216: 
        !           217:                deflab( retlab );
        !           218: 
        !           219:                stlab = getlab();
        !           220:                printf( "       movl    d0,a0\n" );
        !           221:                printf( "       movl    #L%d,a1\n", stlab );
        !           222:                size = tsize( DECREF(p->stype), p->dimoff, p->sizoff ) / SZCHAR;
        !           223:                printf( "       .bss\nL%d:      .=.+%d\n        .text\n",
        !           224:                        stlab, size );
        !           225:                if (size <= 20) {
        !           226:                        count = size/2;
        !           227:                        while( size ){ /* simple load/store loop */
        !           228:                                count = (size > 2) ? 4 : 2;
        !           229:                                printf("        mov%c   a0@+,a1@+\n",
        !           230:                                        count==2 ? 'w' : 'l');
        !           231:                                size -= count;
        !           232:                        }
        !           233:                } else {
        !           234:                        int residue;
        !           235: 
        !           236:                        count = size / sizeof(long);
        !           237:                        residue = size % sizeof(long);
        !           238:                        if (count > 0x7fff) {
        !           239:                                printf("        movl    #%d,d0\n", count-1);
        !           240:                                printf("1:      movl    a0@+,a1@+\n");
        !           241:                                printf("        dbra    d0,1b\n");
        !           242:                                printf("        subql   #1,d0\n");
        !           243:                                printf("        jcc     1b\n");
        !           244:                        } else {
        !           245:                                printf("        movw    #%d,d0\n", count-1);
        !           246:                                printf("1:      movl    a0@+,a1@+\n");
        !           247:                                printf("        dbra    d0,1b\n");
        !           248:                        }
        !           249:                        switch(residue) {
        !           250:                        case 1:
        !           251:                                printf("        movb    a0@+,a1@+\n");
        !           252:                                break;
        !           253:                        case 2:
        !           254:                                printf("        movw    a0@+,a1@+\n");
        !           255:                                break;
        !           256:                        case 3:
        !           257:                                printf("        movw    a0@+,a1@+\n");
        !           258:                                printf("        movb    a0@+,a1@+\n");
        !           259:                                break;
        !           260:                        default:
        !           261:                                break;
        !           262:                        }
        !           263:                }
        !           264:                printf( "       movl    #L%d,d0\n", stlab );
        !           265:                /* turn off strftn flag, so return sequence will be generated */
        !           266:                strftn = 0;
        !           267:                }
        !           268:        /* branch( retlab ); */
        !           269:        p2bend();
        !           270:        if (gdebug && oldway)
        !           271:                dbfunend(labelno++);
        !           272:        fdefflag = 0;
        !           273: #endif
        !           274: }
        !           275: 
        !           276: int ftlab1, ftlab2;
        !           277: 
        !           278: bfcode( a, n ) int a[]; 
        !           279: {
        !           280:        /* code for the beginning of a function; a is an array of
        !           281:                indices in stab for the arguments; n is the number */
        !           282:        register i;
        !           283:        register temp;
        !           284:        register struct symtab *p;
        !           285:        int off;
        !           286:        char *toreg();
        !           287: 
        !           288:        locctr( PROG );
        !           289:        p = STP(curftn);
        !           290:        if (p == NULL) return;
        !           291:        temp = p->stype;
        !           292:        temp = DECREF(temp);
        !           293: #ifdef VAX
        !           294:        printf( "       .align  1\n");
        !           295: #else
        !           296:        /* magic cookie for c2 */
        !           297:        /* uses old (pre-TERROR) type format */
        !           298:        printf( "|#PROC# %#o\n", (temp&BTMASK) | ((temp&~BTMASK)>>2) );
        !           299: #endif
        !           300:        defnam( p );
        !           301:        strftn = (temp==STRTY) || (temp==UNIONTY);
        !           302:        fltfun = (temp==FLOAT) || (temp==DOUBLE);
        !           303: 
        !           304:        retlab = getlab();
        !           305: 
        !           306:        /* routine prolog */
        !           307: 
        !           308: #ifdef VAX
        !           309:        printf( "       .word   L%d\n", ftnno);
        !           310: #else  !VAX
        !           311:        printf("        link    a6,#0\n");
        !           312:        printf("        addl    #-LF%d,sp\n", ftnno);
        !           313: #ifdef STACKPROBE
        !           314:        if (noprobe!=1){
        !           315:            printf("    tstb    sp@(-LP%d)\n",ftnno);
        !           316:        }
        !           317: #endif
        !           318:        printf("        moveml  #LS%d,sp@\n",ftnno);
        !           319:        if (use68881) {
        !           320:                /*
        !           321:                 * save floating registers used for variables
        !           322:                 */
        !           323:                if (use68020) {
        !           324:                        printf("        fmovem  #LSS%d,a6@(-LFF%d:l)\n",
        !           325:                                ftnno, ftnno);
        !           326:                } else {
        !           327:                        /* 68881 without 68020; unlikely combination */
        !           328:                        printf("        movl    #-LFF%d,a0\n", ftnno);
        !           329:                        printf("        fmovem  #LSS%d,a6@(0,a0:l)\n", ftnno);
        !           330:                }
        !           331:        }
        !           332: #endif !VAX
        !           333: 
        !           334: #ifdef VAX
        !           335:        ftlab1 = getlab();
        !           336:        ftlab2 = getlab();
        !           337:        printf( "       jbr     L%d\n", ftlab1);
        !           338:        printf( "L%d:\n", ftlab2);
        !           339: #endif
        !           340:        if( proflg ) {  /* profile code */
        !           341:                i = getlab();
        !           342: #ifdef VAX
        !           343:                printf("        movab   L%d,r0\n", i);
        !           344:                printf("        jsb     mcount\n");
        !           345:                printf("        .data\n");
        !           346:                printf("        .align  2\n");
        !           347:                printf("L%d:    .long   0\n", i);
        !           348:                printf("        .text\n");
        !           349: #else
        !           350:                printf("        movl    #L%d,a0\n",i);
        !           351:                printf("        jsr     mcount\n");
        !           352:                printf("        .bss\n  .even\n");
        !           353:                printf("L%d:    .skip   4\n     .text\n",i);
        !           354: #endif
        !           355:                psline(lineno);
        !           356:                }
        !           357: 
        !           358:        off = ARGINIT;
        !           359: 
        !           360:        for( i=0; i<n; ++i ){
        !           361: #ifndef VAX
        !           362:                char type;
        !           363: #endif
        !           364: 
        !           365:                p = STP(a[i]);
        !           366:                if( p->sclass == REGISTER ){
        !           367:                        temp = p->offset;  /* save register number */
        !           368:                        p->sclass = PARAM;  /* forget that it is a register */
        !           369:                        p->offset = NOOFFSET;
        !           370:                        oalloc( p, &off );
        !           371: #ifdef VAX
        !           372: /*tbl*/                        printf( "       %s      %d(ap),r%d\n",
        !           373:                                toreg(p->stype), p->offset/SZCHAR, temp );
        !           374: #else
        !           375:                        printf( "       %s      a6@(%d),%s\n",
        !           376:                                toreg(p->stype), p->offset/SZCHAR,
        !           377:                                rnames[temp]);
        !           378:                        markused(temp);
        !           379: #endif
        !           380:                        p->offset = temp;  /* remember register number */
        !           381:                        p->sclass = REGISTER;   /* remember that it is a register */
        !           382:                        }
        !           383:                /* The 68k doesn't have this code.  I'll try it for a while */
        !           384: #ifdef VAX
        !           385:                else if( p->stype == STRTY || p->stype == UNIONTY ) {
        !           386:                        p->offset = NOOFFSET;
        !           387:                        if( oalloc( p, &off ) ) cerror( "bad argument" );
        !           388:                        SETOFF( off, ALSTACK );
        !           389:                        }
        !           390: #endif
        !           391:                else {
        !           392:                        if( oalloc( p, &off ) ) cerror( "bad argument" );
        !           393:                        }
        !           394: 
        !           395:                }
        !           396:        if (gdebug && !oldway)
        !           397:                psline(lineno);
        !           398:        fdefflag = 1;
        !           399: }
        !           400: 
        !           401: bccode()
        !           402: { /* called just before the first executable statment */
        !           403:                /* by now, the automatics and register variables are allocated */
        !           404:        SETOFF( autooff, SZINT );
        !           405:        /* set aside store area offset */
        !           406:        p2bbeg( autooff, regvar );
        !           407: #ifdef VAX
        !           408:        reg_use = (reg_use > regvar ? regvar : reg_use);
        !           409: #endif
        !           410: }
        !           411: 
        !           412: ejobcode( flag )
        !           413: {
        !           414:        /* called just before final exit */
        !           415:        /* flag is 1 if errors, 0 if none */
        !           416:        if (gdebug) {
        !           417:                printf("\t.text\n");
        !           418:                pstab(NULLNAME, N_ESO);
        !           419:                printf("0,0,LL%d\n", labelno);
        !           420:                printf("LL%d:\n", labelno++);
        !           421:        }
        !           422: }
        !           423: 
        !           424: aobeg()
        !           425: {
        !           426:        /* called before removing automatics from stab */
        !           427: }
        !           428: 
        !           429: aocode(p) struct symtab *p; 
        !           430: {
        !           431:        /* called when automatic p removed from stab */
        !           432: }
        !           433: 
        !           434: aoend()
        !           435: {
        !           436:        /* called after removing all automatics from stab */
        !           437: }
        !           438: 
        !           439: defnam( p ) register struct symtab *p; 
        !           440: {
        !           441:        /* define the current location as the name p->sname */
        !           442: 
        !           443:        if( p->sclass == EXTDEF ){
        !           444:                printf( "       .globl  %s\n", exname( p->sname ) );
        !           445:                }
        !           446:        if( p->sclass == STATIC && p->slevel>1 ) deflab( p->offset );
        !           447:        else printf( "%s:\n", exname( p->sname ) );
        !           448: 
        !           449: }
        !           450: 
        !           451: bycode( t, i )
        !           452: {
        !           453: #ifdef ASSTRINGS
        !           454: static int     lastoctal = 0;
        !           455: #endif
        !           456: 
        !           457:        /* put byte i+1 in a string */
        !           458: 
        !           459: #ifdef ASSTRINGS
        !           460: 
        !           461:        i &= 077;
        !           462:        if ( t < 0 ){
        !           463:                if ( i != 0 )   printf( "\"\n" );
        !           464:        } else {
        !           465:                if ( i == 0 ) printf("\t.ascii\t\"");
        !           466:                if ( t == '\\' || t == '"'){
        !           467:                        lastoctal = 0;
        !           468:                        printf("\\%c", t);
        !           469:                }
        !           470:                        /*
        !           471:                         *      We escape the colon in strings so that
        !           472:                         *      c2 will, in its infinite wisdom, interpret
        !           473:                         *      the characters preceding the colon as a label.
        !           474:                         *      If we didn't escape the colon, c2 would
        !           475:                         *      throw away any trailing blanks or tabs after
        !           476:                         *      the colon, but reconstruct a assembly
        !           477:                         *      language semantically correct program.
        !           478:                         *      C2 hasn't been taught about strings.
        !           479:                         */
        !           480:                else if ( t == ':' || t < 040 || t >= 0177 || t == '|' || t == ';' ){
        !           481:                        lastoctal++;
        !           482:                        printf("\\%o",t);
        !           483:                }
        !           484:                else if ( lastoctal && '0' <= t && t <= '9' ){
        !           485:                        lastoctal = 0;
        !           486:                        printf("\"\n\t.ascii\t\"%c", t );
        !           487:                }
        !           488:                else
        !           489:                {       
        !           490:                        lastoctal = 0;
        !           491:                        putchar(t);
        !           492:                }
        !           493:                if ( i == 077 ) printf("\"\n");
        !           494:        }
        !           495: #else
        !           496: 
        !           497:        i &= 07;
        !           498:        if( t < 0 ){ /* end of the string */
        !           499:                if( i != 0 ) printf( "\n" );
        !           500:                }
        !           501: 
        !           502:        else { /* stash byte t into string */
        !           503:                if( i == 0 ) printf( "  .byte   " );
        !           504:                else printf( "," );
        !           505: #ifdef VAX
        !           506:                printf( "0x%x", t );
        !           507: #else
        !           508:                printf( "0x%x", t );
        !           509: #endif
        !           510:                if( i == 07 ) printf( "\n" );
        !           511:                }
        !           512: #endif
        !           513: }
        !           514: 
        !           515: zecode( n )
        !           516: {
        !           517:        /* n integer words of zeros */
        !           518:        OFFSZ temp;
        !           519: #ifndef VAX
        !           520:        register i;
        !           521: #endif
        !           522: 
        !           523:        if( n <= 0 ) return;
        !           524: #ifdef VAX
        !           525:        printf( "       .space  %d\n", (SZINT/SZCHAR)*n );
        !           526: #else
        !           527:        printf( "       .skip   %d\n", (SZINT/SZCHAR)*n );
        !           528: #endif
        !           529:        temp = n;
        !           530:        inoff += temp*SZINT;
        !           531: }
        !           532: 
        !           533: fldal( t ) unsigned t; 
        !           534: { /* return the alignment of field of type t */
        !           535:        uerror( "illegal field type" );
        !           536:        return( ALINT );
        !           537: }
        !           538: 
        !           539: fldty( p ) struct symtab *p; 
        !           540: { /* fix up type of field p */
        !           541:        ;
        !           542: }
        !           543: 
        !           544: 
        !           545: where(c)
        !           546: { /* print location of error  */
        !           547:        /* c is either 'u', 'c', or 'w' */
        !           548:        /* GCOS version */
        !           549:        fprintf( stderr, "%s, line %d: ", ftitle, lineno );
        !           550: }
        !           551: 
        !           552: 
        !           553: /* tbl - toreg() returns a pointer to a char string
        !           554:                  which is the correct  "register move" for the passed type 
        !           555:  */
        !           556: struct type_move 
        !           557: {TWORD fromtype; char tostrng[8];} toreg_strs[] =
        !           558:        {
        !           559: #ifdef VAX
        !           560:        CHAR, "cvtbl",
        !           561:        SHORT, "cvtwl",
        !           562:        INT, "movl",
        !           563:        LONG, "movl",
        !           564:        FLOAT, "movf",
        !           565:        DOUBLE, "movd",
        !           566:        UCHAR,  "movzbl",
        !           567:        USHORT, "movzwl",
        !           568:        UNSIGNED,       "movl",
        !           569:        ULONG,  "movl",
        !           570: #else
        !           571:        CHAR, "movb",
        !           572:        UCHAR, "movb",
        !           573:        SHORT, "movw",
        !           574:        USHORT, "movw",
        !           575: #endif
        !           576:        -1, ""
        !           577:        };
        !           578: 
        !           579: char
        !           580: *toreg(type)
        !           581:        TWORD type;
        !           582: {
        !           583:        struct type_move *p;
        !           584: 
        !           585:        for ( p=toreg_strs; p->fromtype > 0; p++)
        !           586:                if (p->fromtype == type)
        !           587:                        return(p->tostrng);
        !           588: 
        !           589:        /* type not found, must be a pointer type */
        !           590:        if (use68881 && type == FLOAT) {
        !           591:                return("fmoves");
        !           592:        }
        !           593:        if (use68881 && type == DOUBLE) {
        !           594:                return("fmoved");
        !           595:        }
        !           596:        return("movl");
        !           597: }
        !           598: /* tbl */
        !           599: 
        !           600: 
        !           601: main( argc, argv ) char *argv[]; 
        !           602: {
        !           603:        int v;
        !           604: #ifdef BUFSTDERR
        !           605:        char errbuf[BUFSIZ];
        !           606:        setbuf(stderr, errbuf);
        !           607: #endif
        !           608: /*     ffloat_(); /* HACK -- avoid sky board even if present */
        !           609:        v = mainp1( argc, argv );
        !           610:        floatnote();
        !           611:        exit( v );
        !           612: }
        !           613: 
        !           614: struct sw heapsw[SWITSZ];      /* heap for switches */
        !           615: 
        !           616: genswitch(p,n) register struct sw *p;
        !           617: {
        !           618:        /*      p points to an array of structures, each consisting
        !           619:                of a constant value and a label.
        !           620:                The first is >=0 if there is a default label;
        !           621:                its value is the label number
        !           622:                The entries p[1] to p[n] are the nontrivial cases
        !           623:                */
        !           624:        register i;
        !           625:        register CONSZ j, range;
        !           626:        register dlab, swlab;
        !           627: 
        !           628:        range = p[n].sval-p[1].sval;
        !           629: 
        !           630:        if( range>0 && range <= 3*n && n>=4 ){ /* implement a direct switch */
        !           631: 
        !           632:                dlab = p->slab >= 0 ? p->slab : getlab();
        !           633: #ifdef VAX
        !           634:                swlab = getlab();
        !           635: 
        !           636:                /* already in r0 */
        !           637:                printf("        casel   r0,$%ld,$%ld\n", p[1].sval, range);
        !           638:                printf("L%d:\n", swlab);
        !           639:                for( i=1,j=p[1].sval; i<=n; j++) {
        !           640:                        printf("        .word   L%d-L%d\n", (j == p[i].sval ? ((j=p[i++].sval), p[i-1].slab) : dlab),
        !           641:                                swlab);
        !           642:                        }
        !           643: 
        !           644:                if( p->slab >= 0 ) branch( dlab );
        !           645:                else printf("L%d:\n", dlab);
        !           646: #else
        !           647:                if( p[1].sval ){
        !           648:                        printf( "       subl    #" );
        !           649:                        printf( CONFMT, p[1].sval );
        !           650:                        printf( ",d0\n" );
        !           651:                        }
        !           652: 
        !           653:                /* note that this is a cl; it thus checks
        !           654:                   for numbers below range as well as out of range.
        !           655:                   */
        !           656:                printf( "       cmpl    #%ld,d0\n", range );
        !           657:                printf( "       jhi     L%d\n", dlab );
        !           658: 
        !           659:                if (use68020) {
        !           660:                        printf( "       movw    pc@(6,d0:w:2),d0\n" );
        !           661:                } else {
        !           662:                        printf( "       addw    d0,d0\n" );
        !           663:                        printf( "       movw    pc@(6,d0:w),d0\n" );
        !           664:                }
        !           665:                printf( "       jmp     pc@(2,d0:w)\n" );
        !           666: 
        !           667:                /* output table */
        !           668: 
        !           669:   /*   printf( "L%d = \n", swlab=getlab() ); */
        !           670:                printf( "L%d:  \n", swlab=getlab() );
        !           671:                for( i=1,j=p[1].sval; i<=n; ++j )
        !           672:                        printf( "       .word   L%d-L%d\n", ( j == p[i].sval ) ?
        !           673:                                p[i++].slab : dlab, swlab );
        !           674:                if( p->slab< 0 ) deflab( dlab );
        !           675: #endif
        !           676:                return;
        !           677: 
        !           678:                }
        !           679: 
        !           680:        if( n>8 ) {     /* heap switch */
        !           681: #ifdef VAX
        !           682:                heapsw[0].slab = dlab = p->slab >= 0 ? p->slab : getlab();
        !           683:                makeheap(p, n, 1);      /* build heap */
        !           684: 
        !           685:                walkheap(1, n); /* produce code */
        !           686: 
        !           687:                if( p->slab >= 0 )
        !           688:                        branch( dlab );
        !           689:                else
        !           690:                        printf("L%d:\n", dlab);
        !           691:                return;
        !           692: #else
        !           693:                /* drop comparison loop, then switch table, then comparison table */
        !           694:                int tbllab, llab;
        !           695:                int biggest, smallest, range;
        !           696:                char sizechar;
        !           697:                char *sizeword;
        !           698:                int unsgned = 1;
        !           699:                tbllab = getlab();
        !           700:                dlab = p->slab>=0 ? p->slab : getlab();
        !           701:                biggest = p[n].sval;
        !           702:                smallest = p[1].sval;
        !           703:                range = biggest-smallest;
        !           704:                if   (biggest<=0377 && smallest>=0){
        !           705:                    sizechar = 'b';sizeword = ".byte"; 
        !           706:                    smallest = 0;
        !           707:                }else if ( range<=0377 && range > 0 ){
        !           708:                    sizechar = 'b';sizeword = ".byte";
        !           709:                }else if (biggest<=0177777 && smallest>=0){
        !           710:                    sizechar = 'w';sizeword = ".word"; 
        !           711:                    smallest = 0;
        !           712:                }else if ( range<=0177777 && range > 0 ){
        !           713:                    sizechar = 'w';sizeword = ".word";
        !           714:                }else{
        !           715:                    sizechar = 'l';sizeword = ".long"; smallest = 0; unsgned = 0;
        !           716:                }
        !           717: 
        !           718:                if( smallest ){
        !           719:                    printf( "   %sl     #%d,d0\n", smallest<0?"add":"sub",
        !           720:                                abs(smallest) );
        !           721:                    printf( "   cmpl    #%d,d0\n", range );
        !           722:                    printf( "   jhi     L%d\n", dlab );
        !           723:                } else if (sizechar != 'l' ){
        !           724:                    printf( "   cmpl    #%d,d0\n", biggest );
        !           725:                    printf( "   jhi     L%d\n", dlab );
        !           726:                }
        !           727:                printf( "       lea     L%d,a0\n        mov%s   #%d,d1\n",
        !           728:                        tbllab, (n<=128)?"eq":"w",n-1);
        !           729:                llab = getlab();
        !           730:                printf( "L%d:   cmp%c   a0@+,d0\n       db%s    d1,L%d\n",
        !           731:                        llab, sizechar, unsgned?"cc":"ge", llab);
        !           732:                printf( "       jne     L%d\n", dlab );
        !           733:                if (use68020) {
        !           734:                        printf( "       movw    pc@(6,d1:w:2),d0\n" );
        !           735:                } else {
        !           736:                        printf( "       addw    d1,d1\n" );
        !           737:                        printf( "       movw    pc@(6,d1:w),d0\n" );
        !           738:                }
        !           739:                printf( "       jmp     pc@(2,d0:w)\n" );
        !           740:                /* put out statement list forwards, comparison table backwards*/
        !           741:                printf( "L%d:  \n", swlab=getlab() );
        !           742:                for( i=1; i<=n; i++ )
        !           743:                        printf( "       .word   L%d-L%d\n", p[i].slab, swlab );
        !           744:                printf( "L%d:  \n", tbllab );
        !           745:                for( i=n; i>=1; i-- )
        !           746:                    printf( "   %s      %d\n", sizeword, p[i].sval-smallest );
        !           747:                if (sizechar == 'b')
        !           748:                    printf("    .even\n");
        !           749:                if( p->slab< 0 ) deflab( dlab );
        !           750:                return;
        !           751: #endif
        !           752:        }
        !           753: 
        !           754:        /* debugging code */
        !           755: 
        !           756:        /* out for the moment
        !           757:        if( n >= 4 ) werror( "inefficient switch: %d, %d", n, (int) (range/n) );
        !           758:        */
        !           759: 
        !           760:        /* simple switch code */
        !           761: 
        !           762:        for( i=1; i<=n; ++i ){
        !           763:                /* already in r0 */
        !           764: 
        !           765: #ifdef VAX
        !           766:                printf( "       cmpl    r0,$" );
        !           767: #else
        !           768:                printf( "       cmpl    #" );
        !           769: #endif
        !           770:                printf( CONFMT, p[i].sval );
        !           771: #ifdef VAX
        !           772:                printf( "\n     jeql    L%d\n", p[i].slab );
        !           773: #else
        !           774:                printf( ",d0\n  jeq     L%d\n", p[i].slab );
        !           775: #endif
        !           776:                }
        !           777: 
        !           778:        if( p->slab>=0 ) branch( p->slab );
        !           779: }
        !           780: 
        !           781: #ifdef VAX
        !           782: 
        !           783: makeheap(p, m, n)
        !           784: register struct sw *p;
        !           785: {
        !           786:        register int q;
        !           787: 
        !           788:        q = select(m);
        !           789:        heapsw[n] = p[q];
        !           790:        if( q>1 ) makeheap(p, q-1, 2*n);
        !           791:        if( q<m ) makeheap(p+q, m-q, 2*n+1);
        !           792: }
        !           793: 
        !           794: select(m) 
        !           795: {
        !           796:        register int l,i,k;
        !           797: 
        !           798:        for(i=1; ; i*=2)
        !           799:                if( (i-1) > m ) break;
        !           800:        l = ((k = i/2 - 1) + 1)/2;
        !           801:        return( l + (m-k < l ? m-k : l));
        !           802: }
        !           803: 
        !           804: walkheap(start, limit)
        !           805: {
        !           806:        int label;
        !           807: 
        !           808: 
        !           809:        if( start > limit ) return;
        !           810: #ifdef VAX
        !           811:                printf( "       cmpl    r0,$" );
        !           812: #else
        !           813:                printf( "       cmpl    #" );
        !           814: #endif
        !           815:                printf( CONFMT, heapsw[start].sval );
        !           816: #ifdef VAX
        !           817:                printf( "\n     jeql    L%d\n", heapsw[start].slab );
        !           818: #else
        !           819:                printf( ",d0\n  beq     L%d\n", heapsw[start].slab );
        !           820: #endif
        !           821:        if( (2*start) > limit ) {
        !           822: #ifdef VAX
        !           823:                printf("        jbr     L%d\n", heapsw[0].slab);
        !           824: #else
        !           825:                printf("        bra     L%d\n", heapsw[0].slab);
        !           826: #endif
        !           827:                return;
        !           828:        }
        !           829:        if( (2*start+1) <= limit ) {
        !           830:                label = getlab();
        !           831: #ifdef VAX
        !           832:                printf("        jgtr    L%d\n", label);
        !           833: #else
        !           834:                printf("        bgt     L%d\n", label);
        !           835: #endif 
        !           836:        } else
        !           837: #ifdef VAX 
        !           838:                printf("        jgtr    L%d\n", heapsw[0].slab);
        !           839: #else 
        !           840:                printf("        bgt     L%d\n", heapsw[0].slab);
        !           841: #endif 
        !           842:        walkheap( 2*start, limit);
        !           843:        if( (2*start+1) <= limit ) {
        !           844:                printf("L%d:\n", label);
        !           845:                walkheap( 2*start+1, limit);
        !           846:        }
        !           847: }
        !           848: #endif VAX heap code

unix.superglobalmegacorp.com

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