Annotation of 43BSDReno/libexec/pcc/ccom.vax/local.c, revision 1.1.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.