Annotation of 43BSDTahoe/lib/pcc/pcc.vax/local.c, revision 1.1

1.1     ! root        1: #ifndef lint
        !             2: static char *sccsid ="@(#)local.c      1.17 (Berkeley) 5/11/88";
        !             3: #endif lint
        !             4: 
        !             5: # include "pass1.h"
        !             6: 
        !             7: /*     this file contains code which is dependent on the target machine */
        !             8: 
        !             9: NODE *
        !            10: clocal(p) register NODE *p; {
        !            11: 
        !            12:        /* this is called to do local transformations on
        !            13:           an expression tree preparitory to its being
        !            14:           written out in intermediate code.
        !            15:        */
        !            16: 
        !            17:        /* the major essential job is rewriting the
        !            18:           automatic variables and arguments in terms of
        !            19:           REG and OREG nodes */
        !            20:        /* conversion ops which are not necessary are also clobbered here */
        !            21:        /* in addition, any special features (such as rewriting
        !            22:           exclusive or) are easily handled here as well */
        !            23: 
        !            24:        register struct symtab *q;
        !            25:        register NODE *r;
        !            26:        register int o;
        !            27:        register int m, ml;
        !            28: 
        !            29:        switch( o = p->in.op ){
        !            30: 
        !            31:        case NAME:
        !            32:                if( p->tn.rval < 0 ) { /* already processed; ignore... */
        !            33:                        return(p);
        !            34:                        }
        !            35:                q = &stab[p->tn.rval];
        !            36:                switch( q->sclass ){
        !            37: 
        !            38:                case AUTO:
        !            39:                case PARAM:
        !            40:                        /* fake up a structure reference */
        !            41:                        r = block( REG, NIL, NIL, PTR+STRTY, 0, 0 );
        !            42:                        r->tn.lval = 0;
        !            43:                        r->tn.rval = (q->sclass==AUTO?STKREG:ARGREG);
        !            44:                        p = stref( block( STREF, r, p, 0, 0, 0 ) );
        !            45:                        break;
        !            46: 
        !            47:                case ULABEL:
        !            48:                case LABEL:
        !            49:                case STATIC:
        !            50:                        if( q->slevel == 0 ) break;
        !            51:                        p->tn.lval = 0;
        !            52:                        p->tn.rval = -q->offset;
        !            53:                        break;
        !            54: 
        !            55:                case REGISTER:
        !            56:                        p->in.op = REG;
        !            57:                        p->tn.lval = 0;
        !            58:                        p->tn.rval = q->offset;
        !            59:                        break;
        !            60: 
        !            61:                        }
        !            62:                break;
        !            63: 
        !            64:        case LT:
        !            65:        case LE:
        !            66:        case GT:
        !            67:        case GE:
        !            68:                if( ISPTR( p->in.left->in.type ) || ISPTR( p->in.right->in.type ) ){
        !            69:                        p->in.op += (ULT-LT);
        !            70:                        }
        !            71:                break;
        !            72: 
        !            73:        case PCONV:
        !            74:                /* do pointer conversions for char and longs */
        !            75:                ml = p->in.left->in.type;
        !            76:                if( ( ml==CHAR || ml==UCHAR || ml==SHORT || ml==USHORT ) && p->in.left->in.op != ICON ) break;
        !            77: 
        !            78:                /* pointers all have the same representation; the type is inherited */
        !            79: 
        !            80:                p->in.left->in.type = p->in.type;
        !            81:                p->in.left->fn.cdim = p->fn.cdim;
        !            82:                p->in.left->fn.csiz = p->fn.csiz;
        !            83:                p->in.op = FREE;
        !            84:                return( p->in.left );
        !            85: 
        !            86:        case SCONV:
        !            87:                m = p->in.type;
        !            88:                ml = p->in.left->in.type;
        !            89:                if(m == ml)
        !            90:                        goto clobber;
        !            91:                o = p->in.left->in.op;
        !            92:                if(m == FLOAT || m == DOUBLE) {
        !            93:                        if(o==SCONV &&
        !            94:                         ml == DOUBLE &&
        !            95:                         p->in.left->in.left->in.type==m) {
        !            96:                                p->in.op = p->in.left->in.op = FREE;
        !            97:                                return(p->in.left->in.left);
        !            98:                                }
        !            99:                        /* see makety() for constant conversions */
        !           100:                        break;
        !           101:                        }
        !           102:                if(ml == FLOAT || ml == DOUBLE){
        !           103:                        if(o != FCON && o != DCON)
        !           104:                                break;
        !           105:                        ml = ISUNSIGNED(m) ? UNSIGNED : INT; /* LONG? */
        !           106:                        r = block( ICON, (NODE *)NULL, (NODE *)NULL, ml, 0, 0 );
        !           107:                        if( o == FCON )
        !           108:                                r->tn.lval = ml == INT ?
        !           109:                                        (int) p->in.left->fpn.fval :
        !           110:                                        (unsigned) p->in.left->fpn.fval;
        !           111:                        else
        !           112:                                r->tn.lval = ml == INT ?
        !           113:                                        (int) p->in.left->dpn.dval :
        !           114:                                        (unsigned) p->in.left->dpn.dval;
        !           115:                        r->tn.rval = NONAME;
        !           116:                        p->in.left->in.op = FREE;
        !           117:                        p->in.left = r;
        !           118:                        o = ICON;
        !           119:                        if( m == ml )
        !           120:                                goto clobber;
        !           121:                        }
        !           122:                /* now, look for conversions downwards */
        !           123: 
        !           124:                if( o == ICON ){ /* simulate the conversion here */
        !           125:                        CONSZ val;
        !           126:                        val = p->in.left->tn.lval;
        !           127:                        switch( m ){
        !           128:                        case CHAR:
        !           129:                                p->in.left->tn.lval = (char) val;
        !           130:                                break;
        !           131:                        case UCHAR:
        !           132:                                p->in.left->tn.lval = val & 0XFF;
        !           133:                                break;
        !           134:                        case USHORT:
        !           135:                                p->in.left->tn.lval = val & 0XFFFFL;
        !           136:                                break;
        !           137:                        case SHORT:
        !           138:                                p->in.left->tn.lval = (short)val;
        !           139:                                break;
        !           140:                        case UNSIGNED:
        !           141:                                p->in.left->tn.lval = val & 0xFFFFFFFFL;
        !           142:                                break;
        !           143:                        case INT:
        !           144:                                p->in.left->tn.lval = (int)val;
        !           145:                                break;
        !           146:                                }
        !           147:                        p->in.left->in.type = m;
        !           148:                        }
        !           149:                else
        !           150:                        break;
        !           151: 
        !           152:        clobber:
        !           153:                p->in.op = FREE;
        !           154:                return( p->in.left );  /* conversion gets clobbered */
        !           155: 
        !           156:        case PVCONV:
        !           157:        case PMCONV:
        !           158:                if( p->in.right->in.op != ICON ) cerror( "bad conversion", 0);
        !           159:                p->in.op = FREE;
        !           160:                return( buildtree( o==PMCONV?MUL:DIV, p->in.left, p->in.right ) );
        !           161: 
        !           162:        case RS:
        !           163:        case ASG RS:
        !           164:                /* convert >> to << with negative shift count */
        !           165:                /* only if type of left operand is not unsigned */
        !           166: 
        !           167:                if( ISUNSIGNED(p->in.left->in.type) ) break;
        !           168:                if( p->in.right->in.op != UNARY MINUS )
        !           169:                        p->in.right = buildtree( UNARY MINUS, p->in.right, NIL );
        !           170:                else {
        !           171:                        r = p->in.right;
        !           172:                        p->in.right = p->in.right->in.left;
        !           173:                        r->in.op = FREE;
        !           174:                }
        !           175:                if( p->in.op == RS ) p->in.op = LS;
        !           176:                else p->in.op = ASG LS;
        !           177:                break;
        !           178: 
        !           179:        case FLD:
        !           180:                /* make sure that the second pass does not make the
        !           181:                   descendant of a FLD operator into a doubly indexed OREG */
        !           182: 
        !           183:                if( p->in.left->in.op == UNARY MUL
        !           184:                                && (r=p->in.left->in.left)->in.op == PCONV)
        !           185:                        if( r->in.left->in.op == PLUS || r->in.left->in.op == MINUS ) 
        !           186:                                if( ISPTR(r->in.type) ) {
        !           187:                                        if( ISUNSIGNED(p->in.left->in.type) )
        !           188:                                                p->in.left->in.type = UCHAR;
        !           189:                                        else
        !           190:                                                p->in.left->in.type = CHAR;
        !           191:                                }
        !           192:                break;
        !           193:                }
        !           194: 
        !           195:        return(p);
        !           196:        }
        !           197: 
        !           198: /*ARGSUSED*/
        !           199: andable( p ) NODE *p; {
        !           200:        return(1);  /* all names can have & taken on them */
        !           201:        }
        !           202: 
        !           203: cendarg(){ /* at the end of the arguments of a ftn, set the automatic offset */
        !           204:        autooff = AUTOINIT;
        !           205:        }
        !           206: 
        !           207: cisreg( t ) TWORD t; { /* is an automatic variable of type t OK for a register variable */
        !           208: 
        !           209: #ifdef TRUST_REG_CHAR_AND_REG_SHORT
        !           210:        if( t==INT || t==UNSIGNED || t==LONG || t==ULONG        /* tbl */
        !           211:                || t==CHAR || t==UCHAR || t==SHORT              /* tbl */
        !           212:                || t==USHORT || ISPTR(t)) return(1);            /* tbl */
        !           213: #else
        !           214:        if( t==INT || t==UNSIGNED || t==LONG || t==ULONG        /* wnj */
        !           215: #ifdef SPRECC
        !           216:                || t==FLOAT
        !           217: #endif
        !           218:                || ISPTR(t)) return (1);                        /* wnj */
        !           219: #endif
        !           220:        return(0);
        !           221:        }
        !           222: 
        !           223: /*ARGSUSED*/
        !           224: NODE *
        !           225: offcon( off, t, d, s ) OFFSZ off; TWORD t; {
        !           226: 
        !           227:        /* return a node, for structure references, which is suitable for
        !           228:           being added to a pointer of type t, in order to be off bits offset
        !           229:           into a structure */
        !           230: 
        !           231:        register NODE *p;
        !           232: 
        !           233:        /* t, d, and s are the type, dimension offset, and sizeoffset */
        !           234:        /* in general they  are necessary for offcon, but not on VAX */
        !           235: 
        !           236:        p = bcon(0);
        !           237:        p->tn.lval = off/SZCHAR;
        !           238:        return(p);
        !           239: 
        !           240:        }
        !           241: 
        !           242: 
        !           243: static inwd    /* current bit offsed in word */;
        !           244: static CONSZ word      /* word being built from fields */;
        !           245: 
        !           246: incode( p, sz ) register NODE *p; {
        !           247: 
        !           248:        /* generate initialization code for assigning a constant c
        !           249:                to a field of width sz */
        !           250:        /* we assume that the proper alignment has been obtained */
        !           251:        /* inoff is updated to have the proper final value */
        !           252:        /* we also assume sz  < SZINT */
        !           253: 
        !           254:        inoff += sz;
        !           255:        if(nerrors) return;
        !           256:        if((sz+inwd) > SZINT) cerror("incode: field > int");
        !           257:        word |= ((unsigned)(p->tn.lval<<(32-sz))) >> (32-sz-inwd);
        !           258:        inwd += sz;
        !           259:        if(inoff%SZINT == 0) {
        !           260:                printf( "       .long   0x%lx\n", word);
        !           261:                word = inwd = 0;
        !           262:                }
        !           263:        }
        !           264: 
        !           265: fincode( d, sz ) double d; {
        !           266:        /* output code to initialize space of size sz to the value d */
        !           267:        /* the proper alignment has been obtained */
        !           268:        /* inoff is updated to have the proper final value */
        !           269:        /* on the target machine, write it out in octal! */
        !           270: 
        !           271: 
        !           272:        if(!nerrors)
        !           273:        printf("        %s      0%c%.20e\n", sz == SZDOUBLE ? ".double" : ".float",
        !           274:                sz == SZDOUBLE ? 'd' : 'f', d);
        !           275:        inoff += sz;
        !           276:        }
        !           277: 
        !           278: cinit( p, sz ) NODE *p; {
        !           279:        NODE *l;
        !           280: 
        !           281:        /*
        !           282:         * as a favor (?) to people who want to write
        !           283:         *     int i = 9600/134.5;
        !           284:         * we will, under the proper circumstances, do
        !           285:         * a coercion here.
        !           286:         */
        !           287:        switch (p->in.type) {
        !           288:        case INT:
        !           289:        case UNSIGNED:
        !           290:                l = p->in.left;
        !           291:                if (l->in.op != SCONV ||
        !           292:                    (l->in.left->tn.op != DCON && l->in.left->tn.op != FCON))
        !           293:                        break;
        !           294:                l->in.op = FREE;
        !           295:                l = l->in.left;
        !           296:                l->tn.lval = l->tn.op == DCON ? (long)(l->dpn.dval) :
        !           297:                        (long)(l->fpn.fval);
        !           298:                l->tn.rval = NONAME;
        !           299:                l->tn.op = ICON;
        !           300:                l->tn.type = INT;
        !           301:                p->in.left = l;
        !           302:                break;
        !           303:        }
        !           304:        /* arrange for the initialization of p into a space of size sz */
        !           305:        /* the proper alignment has been opbtained */
        !           306:        /* inoff is updated to have the proper final value */
        !           307:        ecode( p );
        !           308:        inoff += sz;
        !           309:        }
        !           310: 
        !           311: vfdzero( n ){ /* define n bits of zeros in a vfd */
        !           312: 
        !           313:        if( n <= 0 ) return;
        !           314: 
        !           315:        inoff += n;
        !           316:        if (nerrors) return;
        !           317:        inwd += n;
        !           318:        if( inoff%ALINT ==0 ) {
        !           319:                printf( "       .long   0x%lx\n", word );
        !           320:                word = inwd = 0;
        !           321:                }
        !           322:        }
        !           323: 
        !           324: char *
        !           325: exname( p ) char *p; {
        !           326:        /* make a name look like an external name in the local machine */
        !           327: 
        !           328: #ifndef FLEXNAMES
        !           329:        static char text[NCHNAM+1];
        !           330: #else
        !           331:        static char text[BUFSIZ+1];
        !           332: #endif
        !           333: 
        !           334:        register int i;
        !           335: 
        !           336:        text[0] = '_';
        !           337: #ifndef FLEXNAMES
        !           338:        for( i=1; *p&&i<NCHNAM; ++i )
        !           339: #else
        !           340:        for( i=1; *p; ++i )
        !           341: #endif
        !           342:                text[i] = *p++;
        !           343: 
        !           344:        text[i] = '\0';
        !           345: #ifndef FLEXNAMES
        !           346:        text[NCHNAM] = '\0';  /* truncate */
        !           347: #endif
        !           348: 
        !           349:        return( text );
        !           350:        }
        !           351: 
        !           352: ctype( type ) TWORD type;
        !           353:        { /* map types which are not defined on the local machine */
        !           354:        switch( BTYPE(type) ){
        !           355: 
        !           356:        case LONG:
        !           357:                MODTYPE(type,INT);
        !           358:                break;
        !           359: 
        !           360:        case ULONG:
        !           361:                MODTYPE(type,UNSIGNED);
        !           362:                }
        !           363:        return( type );
        !           364:        }
        !           365: 
        !           366: noinit() { /* curid is a variable which is defined but
        !           367:        is not initialized (and not a function );
        !           368:        This routine returns the stroage class for an uninitialized declaration */
        !           369: 
        !           370:        return(EXTERN);
        !           371: 
        !           372:        }
        !           373: 
        !           374: commdec( id ){ /* make a common declaration for id, if reasonable */
        !           375:        register struct symtab *q;
        !           376:        OFFSZ off, tsize();
        !           377: 
        !           378:        if (nerrors) return;
        !           379:        q = &stab[id];
        !           380:        printf( "       .comm   %s,", exname( q->sname ) );
        !           381:        off = tsize( q->stype, q->dimoff, q->sizoff );
        !           382:        printf( CONFMT, off/SZCHAR );
        !           383:        putchar( '\n' );
        !           384:        }
        !           385: 
        !           386: prtdcon(p)
        !           387:        register NODE *p;
        !           388: {
        !           389:        register int o = p->in.op;
        !           390:        int i;
        !           391: 
        !           392:        if (o != DCON && o != FCON)
        !           393:                return;
        !           394:        /*
        !           395:         * Clobber constants of value zero so
        !           396:         * we can generate more efficient code.
        !           397:         */
        !           398:        if ((o == DCON && p->dpn.dval == 0) ||
        !           399:            (o == FCON && p->fpn.fval == 0)) {
        !           400:                p->in.op = ICON;
        !           401:                p->tn.rval = NONAME;
        !           402:                return;
        !           403:        }
        !           404:        locctr(DATA);
        !           405:        defalign(o == DCON ? ALDOUBLE : ALFLOAT);
        !           406:        deflab(i = getlab());
        !           407:        if (o == FCON)
        !           408:                fincode(p->fpn.fval, SZFLOAT);
        !           409:        else
        !           410:                fincode(p->dpn.dval, SZDOUBLE);
        !           411:        p->tn.lval = 0;
        !           412:        p->tn.rval = -i;
        !           413:        p->in.type = (o == DCON ? DOUBLE : FLOAT);
        !           414:        p->in.op = NAME;
        !           415: }
        !           416: 
        !           417: ecode( p ) NODE *p; {
        !           418: 
        !           419:        /* walk the tree and write out the nodes.. */
        !           420: 
        !           421:        if( nerrors ) return;
        !           422:        p2tree( p );
        !           423:        p2compile( p );
        !           424:        }
        !           425: 
        !           426: #ifndef ONEPASS
        !           427: tlen(p) NODE *p; 
        !           428: {
        !           429:        switch(p->in.type) {
        !           430:                case CHAR:
        !           431:                case UCHAR:
        !           432:                        return(1);
        !           433:                        
        !           434:                case SHORT:
        !           435:                case USHORT:
        !           436:                        return(SZSHORT/SZCHAR);
        !           437:                        
        !           438:                case DOUBLE:
        !           439:                        return(SZDOUBLE/SZCHAR);
        !           440:                        
        !           441:                default:
        !           442:                        return(SZINT/SZCHAR);
        !           443:                }
        !           444:        }
        !           445: #endif

unix.superglobalmegacorp.com

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