Annotation of researchv8dc/cmd/ccom/vax/local.c, revision 1.1

1.1     ! root        1: # include <stdio.h>
        !             2: extern int Pflag, bbcnt;
        !             3: # include "mfile1.h"
        !             4: 
        !             5: int minrvar = 11;
        !             6: int wloop_level = LL_BOT;
        !             7: int floop_level = LL_BOT;
        !             8: int maxboff;
        !             9: int maxtemp;
        !            10: codgen(p) 
        !            11: NODE *p;
        !            12: {      extern int bothdebug;
        !            13:        if(bothdebug)
        !            14:                tfree(p);
        !            15: }      /* so pcc2 stuff doesn't get loaded */
        !            16: #if !defined(COMBINED)
        !            17: 
        !            18: main( argc, argv ) char *argv[];
        !            19: {
        !            20:        int r; char errbuf[BUFSIZ];
        !            21: 
        !            22:        setbuf(stderr, errbuf);
        !            23:        r = mainp1( argc, argv );
        !            24:        flushx();
        !            25:        return( r );
        !            26: }
        !            27: 
        !            28: beg_file()
        !            29: {
        !            30:        /* called as the very first thing by the parser to do machine
        !            31:         * dependent stuff
        !            32:         */
        !            33:        regvar = minrvar;
        !            34:        dbfile(NULL);
        !            35: }
        !            36: 
        !            37: #else  /* defined(COMBINED) */
        !            38: 
        !            39: locctr(i)
        !            40: int i;
        !            41: {
        !            42:        static int last = PROG;
        !            43: 
        !            44:        if (i == last)
        !            45:                return;
        !            46:        else if (i == PROG)
        !            47:                printx("        .text\n");
        !            48:        else if (i == DATA)
        !            49:                printx("        .data\n");
        !            50:        else
        !            51:                cerror("funny location counter");
        !            52:        last = i;
        !            53: }
        !            54: 
        !            55: #endif
        !            56: 
        !            57: NODE *
        !            58: treecpy(p)             /* first pass version of tcopy() */
        !            59:        register NODE *p; 
        !            60: {
        !            61:        /* make a fresh copy of p */
        !            62:        register NODE *q;
        !            63: 
        !            64:        q = talloc();
        !            65:        *q = *p;
        !            66:        switch (optype(q->in.op))
        !            67:        {
        !            68:        case BITYPE:
        !            69:                q->in.right = treecpy(p->in.right);
        !            70:        case UTYPE:
        !            71:                q->in.left = treecpy(p->in.left);
        !            72:        }
        !            73:        return (q);
        !            74: }
        !            75: 
        !            76: #if !defined(COMBINED)
        !            77: 
        !            78: NODE *
        !            79: clocal(p) NODE *p;
        !            80: {
        !            81:        register NODE *l,*ll,*r;
        !            82:        if( p->in.op == STAR )
        !            83:        {       /* if it looks like index mode put the  */
        !            84:                /* offset on the right */
        !            85:                l = p->in.left;
        !            86:                if( l->in.op == PLUS )
        !            87:                {
        !            88:                        ll = l->in.left;
        !            89:                        if( ll->in.op != MUL && ll->in.op != UNARY AND )
        !            90:                        {
        !            91:                                if( (l->in.right)->in.op == MUL )
        !            92:                                {
        !            93:                                        r = l->in.right;
        !            94:                                        l->in.right = l->in.left;
        !            95:                                        l->in.left = r;
        !            96:                                }
        !            97:                        }
        !            98:                }
        !            99:        }
        !           100: #ifdef DASSOVCOL
        !           101:        if (!asgbinop(p->in.op) && p->in.op != ASSIGN)
        !           102:                return (p);
        !           103:        r = p->in.right;
        !           104:        if (optype(r->in.op) == LTYPE)
        !           105:                return (p);
        !           106:        l = r->in.left;
        !           107:        if (r->in.op == QUEST || (r->in.op == CONV && l->in.op == QUEST) ||
        !           108:                (r->in.op == CONV && l->in.op == CONV &&
        !           109:                l->in.left->in.op == QUEST))
        !           110:                                /* distribute assigns over colons */
        !           111:        {
        !           112:                register NODE *pwork;
        !           113:                NODE *pcpy = treecpy(p), *pnew;
        !           114: #ifndef NODBG
        !           115:                extern int xdebug, eprint();
        !           116: 
        !           117:                if (xdebug)
        !           118:                {
        !           119:                        puts("Entering [op]=?: distribution");
        !           120:                        eprint(p);
        !           121:                }
        !           122: #endif
        !           123:                pnew = pcpy->in.right;
        !           124:                while (pnew->in.op != QUEST)
        !           125:                        pnew = pnew->in.left;
        !           126:                /*
        !           127:                * pnew is top of new tree
        !           128:                */
        !           129:                if ((pwork = p)->in.right->in.op == QUEST)
        !           130:                {
        !           131:                        tfree(pwork->in.right);
        !           132:                        pwork->in.right = pnew->in.right->in.left;
        !           133:                        pnew->in.right->in.left = pwork;
        !           134:                        /* at this point, 1/2 distributed. Tree looks like:
        !           135:                        *               ASSIGN|ASGOP
        !           136:                        *       LVAL                    QUEST
        !           137:                        *               EXPR1           COLON
        !           138:                        *                       ASSIGN|ASGOP    EXPR3
        !           139:                        *               LVAL            EXPR2
        !           140:                        * pnew "holds" new tree from QUEST node
        !           141:                        */
        !           142:                }
        !           143:                else
        !           144:                {
        !           145:                        NODE *pholdtop = pwork;
        !           146: 
        !           147:                        pwork = pwork->in.right;
        !           148:                        while (pwork->in.left->in.op != QUEST)
        !           149:                                pwork = pwork->in.left;
        !           150:                        tfree(pwork->in.left);
        !           151:                        pwork->in.left = pnew->in.right->in.left;
        !           152:                        pnew->in.right->in.left = pholdtop;
        !           153:                        /* at this point, 1/2 distributed. Tree looks like:
        !           154:                        *               ASSIGN|ASGOP
        !           155:                        *       LVAL                    ANY # OF CONVs
        !           156:                        *                       QUEST
        !           157:                        *               EXPR1           COLON
        !           158:                        *                       ASSIGN|ASGOP    EXPR3
        !           159:                        *               LVAL            ANY # OF CONVs
        !           160:                        *                       EXPR2
        !           161:                        * pnew "holds" new tree from QUEST node
        !           162:                        */
        !           163:                }
        !           164:                if ((pwork = pcpy)->in.right->in.op == QUEST)
        !           165:                {
        !           166:                        pwork->in.right = pnew->in.right->in.right;
        !           167:                        pnew->in.right->in.right = pwork;
        !           168:                        /*
        !           169:                        * done with the easy case
        !           170:                        */
        !           171:                }
        !           172:                else
        !           173:                {
        !           174:                        NODE *pholdtop = pwork;
        !           175: 
        !           176:                        pwork = pwork->in.right;
        !           177:                        while (pwork->in.left->in.op != QUEST)
        !           178:                                pwork = pwork->in.left;
        !           179:                        pwork->in.left = pnew->in.right->in.right;
        !           180:                        pnew->in.right->in.right = pholdtop;
        !           181:                        /*
        !           182:                        * done with the CONVs case
        !           183:                        */
        !           184:                }
        !           185:                p = pnew;
        !           186: #ifndef NODBG
        !           187:                if (xdebug)
        !           188:                {
        !           189:                        puts("Leaving [op]=?: distribution");
        !           190:                        eprint(p);
        !           191:                }
        !           192: #endif
        !           193:        }
        !           194: #endif
        !           195:        return(p);
        !           196: }
        !           197: #endif
        !           198: 
        !           199: cisreg( t ) TWORD t;
        !           200: { /* is an automatic variable of type t OK for a register variable */
        !           201: 
        !           202:        if( t==INT || t==UNSIGNED || ISPTR(t) || t==CHAR || t==UCHAR
        !           203:                   || t==SHORT || t==USHORT || t==FLOAT
        !           204:                   /* (sigh) || t==STRTY || t == UNIONTY*/ )
        !           205:        {
        !           206:                if( regvar >= 6 )
        !           207:                {
        !           208:                        nextrvar = regvar--;
        !           209:                        if( regvar < minrvar ) minrvar = regvar;
        !           210:                        return(1);
        !           211:                }
        !           212:        }
        !           213:        return(0);
        !           214: }
        !           215: 
        !           216: opbigsz( op )
        !           217: {
        !           218:        /* the size below which we do not shrink ops */
        !           219:        switch( op )
        !           220:        {
        !           221: 
        !           222:        default:
        !           223:                return( SZINT );
        !           224: 
        !           225:        case PLUS:
        !           226:        case MINUS:
        !           227:        case OR:
        !           228:        case AND:
        !           229:        case ER:
        !           230:        case COMPL:
        !           231:        case UNARY MINUS:
        !           232:                return( SZCHAR );
        !           233: 
        !           234:        }
        !           235: }
        !           236: 
        !           237: branch(n)                      /* branch to label n or return */
        !           238: int n;
        !           239: {
        !           240:        if (!reached)                   /* return <expr>; } comes here 2x */
        !           241:                return;
        !           242:        genubr(n);
        !           243: }
        !           244: 
        !           245: #if !defined(COMBINED)
        !           246:        /* direct switch beginning */
        !           247: static int tablelabel;
        !           248: 
        !           249: struct sw heapsw[SWITSZ];      /* heap for switches */
        !           250: 
        !           251:        /* test for whether to do a direct switch */
        !           252: # ifndef DSWTEST
        !           253: # define DSWTEST(r,n) (r>0 && r<=(3*n) && n>=4)
        !           254: # endif
        !           255:        /* test for whether to do a heap switch */
        !           256: # ifndef HEAPTEST
        !           257: # define HEAPTEST( n ) (n>8)
        !           258: # endif
        !           259: 
        !           260: genswitch(p,n) register struct sw *p;
        !           261: {
        !           262:        /*      p points to an array of structures, each consisting
        !           263:                of a constant value and a label.
        !           264:                The first is >=0 if there is a default label;
        !           265:                its value is the label number
        !           266:                The entries p[1] to p[n] are the nontrivial cases
        !           267:                */
        !           268:        register i;
        !           269:        register CONSZ j, range;
        !           270:        register dlab, swlab;
        !           271: 
        !           272:        range = p[n].sval-p[1].sval;
        !           273: 
        !           274:        if( DSWTEST( range, n ) )
        !           275:        {       /* implement a direct switch */
        !           276: 
        !           277:                swlab = getlab();
        !           278:                dlab = ((p->slab >= 0) ? p->slab : getlab());
        !           279: 
        !           280:                dswbegin( n, p[1].sval, range, swlab, dlab );
        !           281: 
        !           282:                for( i=1,j=p[1].sval; i<=n; j++)
        !           283:                {
        !           284:                        if( j == p[i].sval )
        !           285:                        {
        !           286:                                dswcase( p[i].slab );
        !           287:                                j = p[i++].sval;
        !           288:                        }
        !           289:                        else
        !           290:                        {
        !           291:                                dswcase( dlab );
        !           292:                        }
        !           293:                }
        !           294: 
        !           295:                /* in case dswbegin changed location counters... */
        !           296:                locctr( PROG );
        !           297: 
        !           298:                if( p->slab >= 0 ) genubr( dlab );
        !           299:                else deflab( dlab );
        !           300:                return;
        !           301:        }
        !           302: 
        !           303:        if( HEAPTEST(n) )
        !           304:        {       /* heap switch */
        !           305: 
        !           306:                heapsw[0].slab = dlab = (p->slab >= 0 ? p->slab : getlab());
        !           307:                makeheap(p, n, 1);      /* build heap */
        !           308:                walkheap(1, n);         /* produce code */
        !           309: 
        !           310:                if( p->slab >= 0 )
        !           311:                        genubr( dlab );
        !           312:                else
        !           313:                        deflab( dlab );
        !           314:                return;
        !           315:        }
        !           316: 
        !           317:        /* simple switch code */
        !           318: 
        !           319:        for( i=1; i<=n; ++i ) sswtest( p[i].sval, p[i].slab );
        !           320:        if( p->slab>=0 ) genubr( p->slab );
        !           321: 
        !           322:        }
        !           323: 
        !           324: makeheap(p, m, n)
        !           325: register struct sw *p;
        !           326: {
        !           327:        register int q;
        !           328: 
        !           329:        q = select(m);
        !           330:        heapsw[n] = p[q];
        !           331:        if( q>1 ) makeheap(p, q-1, 2*n);
        !           332:        if( q<m ) makeheap(p+q, m-q, 2*n+1);
        !           333: }
        !           334: 
        !           335: select(m) {
        !           336:        register int l,i,k;
        !           337: 
        !           338:        for(i=1; ; i*=2)
        !           339:                if( (i-1) > m ) break;
        !           340:        l = ((k = i/2 - 1) + 1)/2;
        !           341:        return( l + (m-k < l ? m-k : l));
        !           342: }
        !           343: 
        !           344: walkheap(start, limit)
        !           345: {
        !           346:        int label;
        !           347: 
        !           348: 
        !           349:        if( start > limit ) return;
        !           350:        sswtest( heapsw[start].sval, heapsw[start].slab );
        !           351:        if( (2*start) > limit ) {
        !           352:                genubr( heapsw[0].slab );
        !           353:                return;
        !           354:        }
        !           355:        if( (2*start+1) <= limit ) {
        !           356:                label = getlab();
        !           357:                hswelse( label );
        !           358:        } else
        !           359:                hswelse( heapsw[0].slab );
        !           360:        walkheap( 2*start, limit);
        !           361:        if( (2*start+1) <= limit ) {
        !           362:                deflab( label );
        !           363:                walkheap( 2*start+1, limit);
        !           364:        }
        !           365: }
        !           366: 
        !           367: 
        !           368: dswbegin( numb, first, range, labl, dlab )
        !           369: CONSZ first, range;
        !           370: int numb, labl, dlab;
        !           371: {
        !           372:        printx("        casel   r0,$%ld,$%ld\n", first, range );
        !           373:        printx("L%d:\n", labl );
        !           374:        tablelabel = labl;
        !           375: }
        !           376: 
        !           377: dswcase( l )
        !           378: int l;
        !           379: {
        !           380:        printx("        .word   L%d-L%d\n", l, tablelabel );
        !           381: }
        !           382: 
        !           383: sswtest( val, lab )
        !           384: CONSZ val;
        !           385: int lab;
        !           386: {
        !           387:        printx( "       cmpl    r0,$%ld\n       jeql    L%d\n", val, lab );
        !           388: }
        !           389: 
        !           390: hswelse( lab )
        !           391: int lab;
        !           392: {
        !           393:        printx("        jgtr    L%d\n", lab );
        !           394: }
        !           395: #endif /* COMBINED */
        !           396: 
        !           397: OFFSZ inoff;           /* size of offset in structure */
        !           398: 
        !           399: static inwd;           /* current bit offset in word */
        !           400: static long word;      /* word being built from fields */
        !           401: 
        !           402: zecode( n )
        !           403: int n;
        !           404: {
        !           405:        /* n integer words of zeros */
        !           406:        if (n <= 0) return;
        !           407:        printx( "       .space  %d\n", 4*n );
        !           408:        inoff += n*SZINT;
        !           409: }
        !           410: 
        !           411: vfdzero( n ){ /* define n bits of zeros in a vfd */
        !           412: 
        !           413:        /* this could be done more cleverly: the following is safe */
        !           414: 
        !           415:        sz_incode( (CONSZ)0, n );
        !           416:        }
        !           417: 
        !           418: incode (p, sz)
        !           419: NODE *p;
        !           420: {
        !           421:        sz_incode(p->tn.lval, sz);
        !           422: }
        !           423: 
        !           424: sz_incode( val, sz )
        !           425: CONSZ val;
        !           426: {
        !           427: 
        !           428:        /* generate initialization code for assigning a constant c
        !           429:                to a field of width sz */
        !           430:        /* we assume that the proper alignment has been obtained */
        !           431:        /* inoff is updated to have the proper final value */
        !           432: 
        !           433:        if((sz+inwd) > SZLONG) cerror("incode: field > long");
        !           434: 
        !           435:        /* this code will have to be replaced if the size of a long on
        !           436:        /* the target machine differs from that on the host machine */
        !           437: 
        !           438: # ifdef RTOLBYTES
        !           439:        word |= ((unsigned)(val<<(SZLONG-sz))) >> (SZLONG-sz-inwd);
        !           440: # else
        !           441:        word |= ((unsigned)(val<<(SZLONG-sz))) >> inwd;
        !           442: # endif
        !           443:        inwd += sz;
        !           444:        inoff += sz;
        !           445: 
        !           446:        /* if initialization can be carried out using shorts, do it */
        !           447: # if (SZSHORT >= ALINIT)
        !           448:        if(inwd == SZSHORT )
        !           449:        {
        !           450: # ifdef RTOLBYTES
        !           451:        genshort( (short) word );
        !           452: # else
        !           453:        genshort( (short) (word>>(SZLONG-SZSHORT)) );
        !           454: # endif
        !           455:        word = inwd = 0;
        !           456:        } else 
        !           457: # endif
        !           458:        if( inwd == SZLONG )
        !           459:        {
        !           460:                genlong( word );
        !           461:                word = inwd = 0;
        !           462:        }
        !           463: }
        !           464: 
        !           465: fincode( d, sz )
        !           466: double d;
        !           467: int sz;
        !           468: {
        !           469:        /* output code to initialize space of size sz to the value d */
        !           470:        /* the proper alignment has been obtained */
        !           471:        /* on the target machine, write it out in hex! */
        !           472: 
        !           473: #if defined(vax)
        !           474:        union { float f; double d; int i[2] } cheat;
        !           475: 
        !           476:        if (sz == SZDOUBLE)
        !           477:        {
        !           478:                cheat.d = d;
        !           479:                printx("\t.long\t0x%x,0x%x\t# %.20e\n", cheat.i[0], cheat.i[1],
        !           480:                    cheat.d);
        !           481:        }
        !           482:        else
        !           483:        {
        !           484:                cheat.f = d;
        !           485:                printx("\t.long\t0x%x\t# %.20e\n", cheat.i[0], cheat.f);
        !           486:        }
        !           487: #else
        !           488:        printx("        %s      0%c%.20e\n",
        !           489:                sz == SZDOUBLE ? ".double" : ".float",
        !           490:                sz == SZDOUBLE ? 'd' : 'f', d);
        !           491: #endif
        !           492:        inoff += sz;
        !           493: 
        !           494: }
        !           495: 
        !           496: int ftlab1, ftlab2;
        !           497: int proflag;
        !           498: 
        !           499: int ent_mask[] = {
        !           500:        0,0,0,0,0, 0xfc0, 0xf80, 0xf00, 0xe00, 0xc00, 0x800, 0};
        !           501: 
        !           502: #if defined(COMBINED)
        !           503: efcode(type)
        !           504: int type;
        !           505: #else
        !           506: efcode()
        !           507: #endif
        !           508: {
        !           509:        /* code for the end of a function */
        !           510:        long spoff;     /* offset from stack pointer */
        !           511: 
        !           512: #if defined(COMBINED)
        !           513:        deflab(retlab);
        !           514:        repl_retval(type);
        !           515:        printx("\tret\n");
        !           516: #else
        !           517:        genret( strftn, strftn, retlab );
        !           518: #endif
        !           519:        printx( "       .set    L.R%d,0x%x\n", ftnno, ent_mask[minrvar] );
        !           520: 
        !           521: #ifdef FORT
        !           522:        spoff = maxboff;
        !           523:        if( spoff >= BITOOR(AUTOINIT) ) spoff -= BITOOR(AUTOINIT);
        !           524:        spoff += maxtemp;
        !           525:        spoff /= SZCHAR;
        !           526:        printx( "       .set    L.F%d,%ld\n", ftnno, spoff / SZCHAR );
        !           527: #else
        !           528:        spoff = maxboff;
        !           529:        if( spoff >= BITOOR(AUTOINIT) ) spoff -= BITOOR(AUTOINIT);
        !           530:        spoff += maxtemp;
        !           531:        spoff /= SZCHAR;
        !           532:        printx("\t.set\tL.SO%d,0x%x\n", ftnno, spoff);
        !           533: #endif
        !           534:        regvar = minrvar = 11;
        !           535: #ifdef GDEBUG
        !           536:        dbfunend(getlab());
        !           537: #endif
        !           538: }
        !           539: 
        !           540: bfcode( a, n )
        !           541: int a[], n;
        !           542: {
        !           543:        /* code for the beginning of a function; a is an array of
        !           544:                indices in stab for the arguments; n is the number */
        !           545:        register i;
        !           546: 
        !           547:        /* routine prolog */
        !           548: 
        !           549:        printx( "       .word   L.R%d\n", ftnno);
        !           550:        printx("\tsubl2\t$L.SO%d,sp\n", ftnno);
        !           551: 
        !           552:        retlab = getlab();
        !           553: 
        !           554:        if( proflag )
        !           555:        {       /* profile code */
        !           556:                i = getlab();
        !           557:                printx("        movab   L%d,r0\n", i);
        !           558:                printx("        jsb     mcount\n");
        !           559:                printx("        .data\n");
        !           560:                printx("        .align  2\n");
        !           561:                printx("L%d:    .long   0\n", i);
        !           562:                printx("        .text\n");
        !           563:        }
        !           564:        if(Pflag) {
        !           565:                printx("\t.data\n\t.comm _proFptr,4\n\t.text\n");
        !           566:                printx("\ttstl locprof+4\n\tbneq L%da\n", ++bbcnt);
        !           567:                printx("\tmovl _proFptr,locprof+4\n\tmoval locprof,_proFptr\n");
        !           568:                printx("#entry %d\n", bbcnt);
        !           569:                printf("L%da:\tincl locprof+%d\n", bbcnt, 4*(bbcnt+3));
        !           570:        }
        !           571: #ifdef GDEBUG
        !           572:        dbfunbeg(&stab[curftn]);
        !           573:        for (i = 0; i < n; ++i) {
        !           574:                extern TWORD argty[];
        !           575:                extern int argsoff[];
        !           576:                struct symtab q;
        !           577:                q = stab[a[i]];
        !           578:                q.sclass = PARAM;
        !           579:                q.stype = argty[i];
        !           580:                q.offset = argsoff[i];
        !           581:                dbfunarg(&q);
        !           582:        }
        !           583: #endif
        !           584: }
        !           585: 
        !           586: defnam( psym )
        !           587: register struct symtab *psym;
        !           588: {
        !           589:        /* define the current location as the name psym->sname
        !           590:         * first give the debugging info for external definitions
        !           591:         */
        !           592:        /*if( psym->slevel == 0 )       /* make sure it's external */
        !           593:        /*      ISFTN(psym->stype) ? prdef(psym,0) : prdef(psym,dsflag);
        !           594:        */
        !           595: 
        !           596:        if (psym->sclass == EXTDEF)
        !           597:                printx( "       .globl  %s\n", exname(psym->sname) );
        !           598:        printx("%s:\n", exname(psym->sname));
        !           599: }
        !           600: 
        !           601: commdec(id)            /* generate a .comm from stab index id */
        !           602: int id;
        !           603: {
        !           604: #if !defined(COMBINED)
        !           605:        register struct symtab *psym;
        !           606:        OFFSZ n;
        !           607: 
        !           608:        psym = &stab[id];
        !           609:        psym->sflags |= SBSS;
        !           610:        n = tsize(psym->stype, psym->dimoff, psym->sizoff) / SZCHAR;
        !           611:        if (psym->sclass == STATIC)
        !           612:                if (psym->slevel)
        !           613:                        printx("        .lcomm  L%d,%ld\n", psym->offset, n);
        !           614:                else    
        !           615:                        printx("        .lcomm  %s,%ld\n", exname(psym->sname), n);
        !           616:        else if (psym->sclass == EXTERN)
        !           617:                printx("        .comm   %s,%ld\n", exname(psym->sname), n);
        !           618: 
        !           619:        else
        !           620:                cerror("Non-static/external in common");
        !           621: #endif
        !           622: }
        !           623: 
        !           624: myfcon(p)
        !           625: NODE *p;
        !           626: {
        !           627:        union { double d; int i[2]; } u;
        !           628: 
        !           629:        u.d = p->fpn.dval;
        !           630:        if (u.i[1] == 0)                /* no significant lo bits, shorten */
        !           631:        {
        !           632:                p->fn.type = FLOAT;
        !           633:                p->fn.csiz = FLOAT;
        !           634:        }
        !           635: }
        !           636: 

unix.superglobalmegacorp.com

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