Annotation of cci/usr/src/lib/fpcc/code.c, revision 1.1.1.2

1.1       root        1: # include "mfile1"
                      2: # include <sys/types.h>
                      3: # include <a.out.h>
                      4: # include <stab.h>
1.1.1.2 ! root        5: # include <signal.h>
1.1       root        6: 
                      7: int proflg = 0;        /* are we generating profiling code? */
                      8: int strftn = 0;  /* is the current function one which returns a value */
                      9: int gdebug;
                     10: int fdefflag;  /* are we within a function definition ? */
                     11: #ifndef STABDOT
                     12: char NULLNAME[8];
                     13: #endif
                     14: int labelno;
                     15: 
                     16: branch( n ){
                     17:        /* output a branch to label n */
                     18:        /* exception is an ordinary function branching to retlab: then, return */
                     19:        if( n == retlab && !strftn ){
                     20:                register TWORD t;
1.1.1.2 ! root       21:                register int r;
1.1       root       22:                        /* set number of regs in assem comment field */
                     23:                        /* so optimizers can do a better job */
                     24:                r = 0;
                     25:                if( retstat & RETVAL ){ /* the function rets a val somewhere */
                     26:                        t = (&stab[curftn])->stype;
                     27:                        t = DECREF(t);
                     28:                        r++;    /* it is at least one */
                     29:                        if(t == DOUBLE)
                     30:                                r++;    /* it takes two */
                     31:                } else          /* the fn does not ret a val    */
                     32:                        r = 2;
                     33:                printf( "       ret#%d\n", r );
                     34:                }
                     35:        else printf( "  jbr     L%d\n", n );
                     36:        }
                     37: 
                     38: int lastloc = { -1 };
                     39: 
                     40: short log2tab[] = {0, 0, 1, 2, 2, 3, 3, 3, 3};
                     41: #define LOG2SZ 9
                     42: 
                     43: defalign(n) {
                     44:        /* cause the alignment to become a multiple of n */
                     45:        n /= SZCHAR;
                     46:        if( lastloc != PROG && n > 1 ) printf( "        .align  %d\n", n >= 0 && n < LOG2SZ ? log2tab[n] : 0 );
                     47:        }
                     48: 
                     49: locctr( l ){
1.1.1.2 ! root       50:        register int temp;
1.1       root       51:        /* l is PROG, ADATA, DATA, STRNG, ISTRNG, or STAB */
                     52: 
                     53:        if( l == lastloc ) return(l);
                     54:        temp = lastloc;
                     55:        lastloc = l;
                     56:        switch( l ){
                     57: 
                     58:        case PROG:
                     59:                printf( "       .text\n" );
                     60:                psline();
                     61:                break;
                     62: 
                     63:        case DATA:
                     64:        case ADATA:
                     65:                printf( "       .data\n" );
                     66:                break;
                     67: 
                     68:        case STRNG:
                     69:                printf( "       .data   1\n" );
                     70:                break;
                     71: 
                     72:        case ISTRNG:
                     73:                printf( "       .data   2\n" );
                     74:                break;
                     75: 
                     76:        case STAB:
                     77:                printf( "       .stab\n" );
                     78:                break;
                     79: 
                     80:        default:
                     81:                cerror( "illegal location counter" );
                     82:                }
                     83: 
                     84:        return( temp );
                     85:        }
                     86: 
                     87: deflab( n ){
                     88:        /* output something to define the current position as label n */
                     89:        printf( "L%d:\n", n );
                     90:        }
                     91: 
                     92: int crslab = 10;
                     93: 
                     94: getlab(){
                     95:        /* return a number usable for a label */
                     96:        return( ++crslab );
                     97:        }
                     98: 
                     99: 
                    100: efcode(){
                    101:        /* code for the end of a function */
                    102: 
                    103:        if( strftn ){  /* copy output (in R2) to caller */
                    104:                register NODE *l, *r;
                    105:                register struct symtab *p;
                    106:                register TWORD t;
                    107:                register int i;
                    108: 
                    109:                p = &stab[curftn];
                    110:                t = p->stype;
                    111:                t = DECREF(t);
                    112: 
                    113:                deflab( retlab );
                    114: 
                    115:                i = getlab();   /* label for return area */
                    116: #ifndef LCOMM
                    117:                printf("        .data\n" );
                    118:                printf("        .align  2\n" );
                    119:                printf("L%d:    .space  %d\n", i, tsize(t, p->dimoff, p->sizoff)/SZCHAR );
                    120:                printf("        .text\n" );
                    121: #else
                    122:                { int sz = tsize(t, p->dimoff, p->sizoff) / SZCHAR;
                    123:                if (sz % (SZINT/SZCHAR))
                    124:                        sz += (SZINT/SZCHAR) - (sz % (SZINT/SZCHAR));
                    125:                printf("        .lcomm  L%d,%d\n", i, sz);
                    126:                }
                    127: #endif
                    128:                psline();
                    129:                printf("        movab   L%d,r1\n", i);
                    130: 
                    131:                reached = 1;
                    132:                l = block( REG, NIL, NIL, PTR|t, p->dimoff, p->sizoff );
                    133:                l->tn.rval = 1;  /* R1 */
                    134:                l->tn.lval = 0;  /* no offset */
                    135:                r = block( REG, NIL, NIL, PTR|t, p->dimoff, p->sizoff );
                    136:                r->tn.rval = 0;  /* R0 */
                    137:                r->tn.lval = 0;
                    138:                l = buildtree( UNARY MUL, l, NIL );
                    139:                r = buildtree( UNARY MUL, r, NIL );
                    140:                l = buildtree( ASSIGN, l, r );
                    141:                l->in.op = FREE;
                    142:                ecomp( l->in.left );
                    143:                printf( "       movab   L%d,r0\n", i );
                    144:                /* turn off strftn flag, so return sequence will be generated */
                    145:                strftn = 0;
                    146:                }
                    147:        branch( retlab );
                    148:        p2bend();
                    149:        fdefflag = 0;
                    150:        }
                    151: 
                    152: int ftlab1, ftlab2;
                    153: 
                    154: bfcode( a, n ) int a[]; {
                    155:        /* code for the beginning of a function; a is an array of
                    156:                indices in stab for the arguments; n is the number */
1.1.1.2 ! root      157:        register int i;
        !           158:        register int temp;
1.1       root      159:        register struct symtab *p;
                    160:        int off;
                    161: #ifdef REG_CHAR
                    162:        char *toreg();
                    163: #endif
                    164:        char *rname();
                    165: 
                    166:        locctr( PROG );
                    167:        p = &stab[curftn];
                    168:        printf( "       .align  1\n");
                    169:        defnam( p );
                    170:        temp = p->stype;
                    171:        temp = DECREF(temp);
                    172:        strftn = (temp==STRTY) || (temp==UNIONTY);
                    173: 
                    174:        retlab = getlab();
                    175: 
                    176:        /* routine prolog */
                    177: 
                    178:        printf( "       .word   L%d\n", ftnno);
                    179:        if (gdebug) {
                    180: #ifdef STABDOT
                    181:                pstabdot(N_SLINE, lineno);
                    182: #else
                    183:                pstab(NULLNAME, N_SLINE);
                    184:                printf("0,%d,LL%d\n", lineno, labelno);
                    185:                printf("LL%d:\n", labelno++);
                    186: #endif
                    187:        }
                    188:        ftlab1 = getlab();
                    189:        ftlab2 = getlab();
                    190:        printf( "       jbr     L%d\n", ftlab1);
                    191:        printf( "L%d:\n", ftlab2);
                    192:        if( proflg ) {  /* profile code */
                    193:                i = getlab();
                    194:                printf("        pushl   $L%d\n", i);
                    195:                printf("        callf   $8,mcount\n");
                    196:                printf("        .data\n");
                    197:                printf("        .align  2\n");
                    198:                printf("L%d:    .long   0\n", i);
                    199:                printf("        .text\n");
                    200:                psline();
                    201:                }
                    202: 
                    203:        off = ARGINIT;
                    204: 
                    205:        for( i=0; i<n; ++i ){
                    206:                p = &stab[a[i]];
                    207:                if( p->sclass == REGISTER ){
                    208:                        temp = p->offset;  /* save register number */
                    209:                        p->sclass = PARAM;  /* forget that it is a register */
                    210:                        p->offset = NOOFFSET;
                    211:                        oalloc( p, &off );
                    212: #ifdef REG_CHAR
                    213:                        printf( "       %s", toreg(p->stype)) );
                    214: #else
                    215:                        printf("        movl");
                    216: #endif
                    217:                        printf( "       %d(fp),%s\n", p->offset/SZCHAR, rname(temp) );
                    218:                        p->offset = temp;  /* remember register number */
                    219:                        p->sclass = REGISTER;   /* remember that it is a register */
                    220: #ifdef REG_CHAR
                    221:                        temp = p->stype;
                    222:                        if( temp==CHAR || temp==SHORT )
                    223:                                p->stype = INT;
                    224:                        else if( temp==UCHAR || temp==USHORT )
                    225:                                p->stype = UNSIGNED;
                    226: #endif
                    227:                        }
                    228:                else if( p->stype == STRTY || p->stype == UNIONTY ) {
                    229:                        p->offset = NOOFFSET;
                    230:                        if( oalloc( p, &off ) ) cerror( "bad argument" );
                    231:                        SETOFF( off, ALSTACK );
                    232:                        }
                    233:                else {
                    234:                        if( oalloc( p, &off ) ) cerror( "bad argument" );
                    235:                        }
                    236: 
                    237:                }
                    238:        fdefflag = 1;
                    239:        }
                    240: 
1.1.1.2 ! root      241: 
        !           242: beg_file() {
        !           243:        /* called as the very first thing by the parser to do machine
        !           244:         * dependent stuff
        !           245:         */
        !           246:        extern fpe_catch();
        !           247:        register char * p;
        !           248:        register char * s;
        !           249: 
        !           250:                        /* note: double quotes already in ftitle... */
        !           251:        /*
        !           252:         * Catch floating exceptions generated by the constant
        !           253:         * folding code.
        !           254:         */
        !           255:        (void) signal( SIGFPE, fpe_catch );
        !           256:        }
        !           257: 
        !           258: fpe_catch() {
        !           259:        /*
        !           260:         * Floating exception generated by constant folding.
        !           261:         */
        !           262:        /* "floating point constant folding causes exception" */
        !           263:        fprintf( stderr, "floating point constant folding causes exception\n");
        !           264:        exit(1);
        !           265:        }
        !           266: 
1.1       root      267: bccode(){ /* called just before the first executable statment */
                    268:                /* by now, the automatics and register variables are allocated */
                    269:        SETOFF( autooff, SZINT );
                    270:        /* set aside store area offset */
                    271:        p2bbeg( autooff, regvar );
                    272:        }
                    273: 
                    274: ejobcode( flag ){
                    275:        /* called just before final exit */
                    276:        /* flag is 1 if errors, 0 if none */
                    277:        }
                    278: 
                    279: aobeg(){
                    280:        /* called before removing automatics from stab */
                    281:        }
                    282: 
                    283: aocode(p) struct symtab *p; {
                    284:        /* called when automatic p removed from stab */
                    285:        }
                    286: 
                    287: aoend(){
                    288:        /* called after removing all automatics from stab */
                    289:        }
                    290: 
                    291: defnam( p ) register struct symtab *p; {
                    292:        /* define the current location as the name p->sname */
                    293: 
                    294:        if( p->sclass == EXTDEF ){
                    295:                printf( "       .globl  %s\n", exname( p->sname ) );
                    296:                }
                    297:        if( p->sclass == STATIC && p->slevel>1 ) deflab( p->offset );
                    298:        else printf( "%s:\n", exname( p->sname ) );
                    299: 
                    300:        }
                    301: 
                    302: bycode( t, i ){
                    303: #ifdef ASSTRINGS
                    304: static int     lastoctal = 0;
                    305: #endif
                    306: 
                    307:        /* put byte i+1 in a string */
                    308: 
                    309: #ifdef ASSTRINGS
                    310: 
                    311:        i &= 077;
                    312:        if ( t < 0 ){
                    313:                if ( i != 0 )   printf( "\"\n" );
                    314:        } else {
                    315:                if ( i == 0 ) printf("\t.ascii\t\"");
                    316:                if ( t == '\\' || t == '"'){
                    317:                        lastoctal = 0;
                    318:                        printf("\\%c", t);
                    319:                }
                    320:                else if ( t < 040 || t >= 0177 ){
                    321:                        lastoctal++;
                    322:                        printf("\\%o",t);
                    323:                }
                    324:                else if ( lastoctal && '0' <= t && t <= '9' ){
                    325:                        lastoctal = 0;
                    326:                        printf("\"\n\t.ascii\t\"%c", t );
                    327:                }
                    328:                else
                    329:                {       
                    330:                        lastoctal = 0;
                    331:                        putchar(t);
                    332:                }
                    333:                if ( i == 077 ) printf("\"\n");
                    334:        }
                    335: #else
                    336: 
                    337:        i &= 07;
                    338:        if( t < 0 ){ /* end of the string */
                    339:                if( i != 0 ) printf( "\n" );
                    340:                }
                    341: 
                    342:        else { /* stash byte t into string */
                    343:                if( i == 0 ) printf( "  .byte   " );
                    344:                else printf( "," );
                    345:                printf( "0x%x", t );
                    346:                if( i == 07 ) printf( "\n" );
                    347:                }
                    348: #endif
                    349:        }
                    350: 
                    351: zecode( n ){
                    352:        /* n integer words of zeros */
                    353:        OFFSZ temp;
                    354:        if( n <= 0 ) return;
                    355:        printf( "       .space  %d\n", (SZINT/SZCHAR)*n );
                    356:        temp = n;
                    357:        inoff += temp*SZINT;
                    358:        }
                    359: 
                    360: fldal( t ) unsigned t; { /* return the alignment of field of type t */
                    361:        uerror( "illegal field type" );
                    362:        return( ALINT );
                    363:        }
                    364: 
                    365: fldty( p ) struct symtab *p; { /* fix up type of field p */
                    366:        ;
                    367:        }
                    368: 
                    369: where(c){ /* print location of error  */
                    370:        /* c is either 'u', 'c', or 'w' */
                    371:        /* GCOS version */
                    372:        fprintf( stderr, "%s, line %d: ", ftitle, lineno );
                    373:        }
                    374: 
                    375: 
                    376: #ifdef REG_CHAR
                    377: /* tbl - toreg() returns a pointer to a char string
                    378:                  which is the correct  "register move" for the passed type 
                    379:  */
                    380: struct type_move {TWORD fromtype; char tostrng[8];} toreg_strs[] =
                    381:        {
                    382:        CHAR, "cvtbl",
                    383:        SHORT, "cvtwl",
                    384:        UCHAR,  "movzbl",
                    385:        USHORT, "movzwl",
                    386:        0, "movl"
                    387:        };
                    388: 
                    389: char
                    390: *toreg(type)
                    391:        TWORD type;
                    392: {
                    393:        struct type_move *p;
                    394: 
                    395:        for ( p=toreg_strs; p->fromtype != 0; p++)
                    396:                if (p->fromtype == type) return(p->tostrng);
                    397: 
                    398:        /* type not found, must be a word type */
                    399:        return(p->tostrng);
                    400: }
                    401: /* tbl */
                    402: #endif
                    403: 
                    404: 
                    405: main( argc, argv ) char *argv[]; {
                    406: #ifdef BUFSTDERR
                    407:        char errbuf[BUFSIZ];
                    408:        setbuf(stderr, errbuf);
                    409: #endif
                    410:        return(mainp1( argc, argv ));
                    411:        }
                    412: 
                    413: struct sw heapsw[SWITSZ];      /* heap for switches */
                    414: 
                    415: genswitch(p,n) register struct sw *p;{
                    416:        /*      p points to an array of structures, each consisting
                    417:                of a constant value and a label.
                    418:                The first is >=0 if there is a default label;
                    419:                its value is the label number
                    420:                The entries p[1] to p[n] are the nontrivial cases
                    421:                */
1.1.1.2 ! root      422:        register int i;
1.1       root      423:        register CONSZ j;
                    424:        register CONSZ unsigned range;
1.1.1.2 ! root      425:        register int dlab, swlab;
1.1       root      426: 
                    427:        range = p[n].sval-p[1].sval;
                    428: 
                    429:        if( range <= 3*n && n>=4 ){ /* implement a direct switch */
                    430: 
                    431:                swlab = getlab();
                    432:                dlab = p->slab >= 0 ? p->slab : getlab();
                    433: 
                    434:                /* already in r0 */
                    435:                printf( "       casel   r0,$" );
                    436:                printf( CONFMT, p[1].sval );
                    437:                printf(",$");
                    438:                printf( CONFMT, range);
                    439:                printf("\n      .align 1\nL%d:\n", swlab);
                    440:                for( i=1,j=p[1].sval; i<=n; j++) {
                    441:                        printf("        .word   L%d-L%d\n", (j == p[i].sval ? ((j=p[i++].sval), p[i-1].slab) : dlab),
                    442:                                swlab);
                    443:                        }
                    444: 
                    445:                if( p->slab >= 0 ) branch( dlab );
                    446:                else printf("L%d:\n", dlab);
                    447:                return;
                    448: 
                    449:                }
                    450: 
                    451:        if( n>8 ) {     /* heap switch */
                    452: 
                    453:                heapsw[0].slab = dlab = p->slab >= 0 ? p->slab : getlab();
                    454:                makeheap(p, n, 1);      /* build heap */
                    455: 
                    456:                walkheap(1, n); /* produce code */
                    457: 
                    458:                if( p->slab >= 0 )
                    459:                        branch( dlab );
                    460:                else
                    461:                        printf("L%d:\n", dlab);
                    462:                return;
                    463:        }
                    464: 
                    465:        /* debugging code */
                    466: 
                    467:        /* out for the moment
                    468:        if( n >= 4 ) werror( "inefficient switch: %d, %d", n, (int) (range/n) );
                    469:        */
                    470: 
                    471:        /* simple switch code */
                    472: 
                    473:        for( i=1; i<=n; ++i ){
                    474:                /* already in r0 */
                    475: 
                    476:                printf( "       cmpl    r0,$" );
                    477:                printf( CONFMT, p[i].sval );
                    478:                printf( "\n     jeql    L%d\n", p[i].slab );
                    479:                }
                    480: 
                    481:        if( p->slab>=0 ) branch( p->slab );
                    482:        }
                    483: 
                    484: makeheap(p, m, n)
                    485: register struct sw *p;
                    486: {
                    487:        register int q;
                    488: 
                    489:        q = select(m);
                    490:        heapsw[n] = p[q];
                    491:        if( q>1 ) makeheap(p, q-1, 2*n);
                    492:        if( q<m ) makeheap(p+q, m-q, 2*n+1);
                    493: }
                    494: 
                    495: select(m) {
                    496:        register int l,i,k;
                    497: 
                    498:        for(i=1; ; i*=2)
                    499:                if( (i-1) > m ) break;
                    500:        l = ((k = i/2 - 1) + 1)/2;
                    501:        return( l + (m-k < l ? m-k : l));
                    502: }
                    503: 
                    504: walkheap(start, limit)
                    505: {
                    506:        int label;
                    507: 
                    508: 
                    509:        if( start > limit ) return;
                    510:        printf( "       cmpl    r0,$" );
                    511:        printf( CONFMT, heapsw[start].sval);
                    512:        printf("\n      jeql    L%d\n", heapsw[start].slab);
                    513:        if( (2*start) > limit ) {
                    514:                printf("        jbr     L%d\n", heapsw[0].slab);
                    515:                return;
                    516:        }
                    517:        if( (2*start+1) <= limit ) {
                    518:                label = getlab();
                    519:                printf("        jgtr    L%d\n", label);
                    520:        } else
                    521:                printf("        jgtr    L%d\n", heapsw[0].slab);
                    522:        walkheap( 2*start, limit);
                    523:        if( (2*start+1) <= limit ) {
                    524:                printf("L%d:\n", label);
                    525:                walkheap( 2*start+1, limit);
                    526:        }
                    527: }

unix.superglobalmegacorp.com

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