Annotation of 3BSD/cmd/pcc/code.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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