Annotation of 43BSDReno/libexec/pcc/ccom.vax/code.c, revision 1.1

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

unix.superglobalmegacorp.com

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