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