Annotation of 43BSDTahoe/lib/old_compiler/pcc/pcc.tahoe/local.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char sccsid[] = "@(#)local.c    1.5 (Berkeley) 1/9/87";
                      3: #endif
                      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 = STKREG;
                     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: #ifdef REG_CHAR
                     60:                        m = p->in.type;
                     61:                        if( m==CHAR || m==SHORT )
                     62:                                p->in.type = INT;
                     63:                        else if( m==UCHAR || m==USHORT )
                     64:                                p->in.type = UNSIGNED;
                     65: #endif
                     66:                        break;
                     67: 
                     68:                        }
                     69:                break;
                     70: 
                     71:        case LT:
                     72:        case LE:
                     73:        case GT:
                     74:        case GE:
                     75:                if( ISPTR( p->in.left->in.type ) || ISPTR( p->in.right->in.type ) ){
                     76:                        p->in.op += (ULT-LT);
                     77:                        }
                     78:                break;
                     79: 
                     80:        case PCONV:
                     81:                /* do pointer conversions for char and longs */
                     82:                ml = p->in.left->in.type;
                     83:                if( ( ml==CHAR || ml==UCHAR || ml==SHORT || ml==USHORT ) && p->in.left->in.op != ICON ) break;
                     84: 
                     85:                /* pointers all have the same representation; the type is inherited */
                     86: 
                     87:        inherit:
                     88:                p->in.left->in.type = p->in.type;
                     89:                p->in.left->fn.cdim = p->fn.cdim;
                     90:                p->in.left->fn.csiz = p->fn.csiz;
                     91:                p->in.op = FREE;
                     92:                return( p->in.left );
                     93: 
                     94:        case SCONV:
                     95:                m = p->in.type;
                     96:                ml = p->in.left->in.type;
                     97:                if(m == FLOAT || m == DOUBLE) {
                     98:                        if(p->in.left->in.op==SCONV &&
                     99:                         ml == DOUBLE &&
                    100:                         p->in.left->in.left->in.type==m) {
                    101:                                p->in.op = p->in.left->in.op = FREE;
                    102:                                return(p->in.left->in.left);
                    103:                        }
                    104:                        if(p->in.left->in.op==FCON)
                    105:                                goto inherit;
                    106:                        break;
                    107:                }
                    108:                if(ml == FLOAT || ml == DOUBLE){
                    109:                        if (p->in.left->in.op == FCON){
                    110:                                p->in.left->in.op = FREE;
                    111:                                p->in.op = ICON;
                    112:                                p->tn.lval = p->in.left->fpn.fval;
                    113:                                p->tn.rval = NONAME;
                    114:                                return(p);
                    115:                        }
                    116:                        break;
                    117:                }
                    118:                /* now, look for conversions downwards */
                    119: 
                    120:                if( p->in.left->in.op == ICON ){        /* simulate the conversion here */
                    121:                        CONSZ val;
                    122:                        val = p->in.left->tn.lval;
                    123:                        switch( m ){
                    124:                        case CHAR:
                    125:                                p->in.left->tn.lval = (char) val;
                    126:                                break;
                    127:                        case UCHAR:
                    128:                                p->in.left->tn.lval = val & 0XFF;
                    129:                                break;
                    130:                        case USHORT:
                    131:                                p->in.left->tn.lval = val & 0XFFFFL;
                    132:                                break;
                    133:                        case SHORT:
                    134:                                p->in.left->tn.lval = (short)val;
                    135:                                break;
                    136:                        case UNSIGNED:
                    137:                                p->in.left->tn.lval = val & 0xFFFFFFFFL;
                    138:                                break;
                    139:                        case INT:
                    140:                                p->in.left->tn.lval = (int)val;
                    141:                                break;
                    142:                                }
                    143:                        p->in.left->in.type = m;
                    144:                } else if (tlen(p) == tlen(p->in.left))
                    145:                        goto inherit;
                    146:                else
                    147:                        break;
                    148:                /* clobber conversion */
                    149:                p->in.op = FREE;
                    150:                return( p->in.left );  /* conversion gets clobbered */
                    151:                break;
                    152: 
                    153:        case QUEST:     /* the right side should be COLON */
                    154:                if((r = p->in.right)->in.op == SCONV) {
                    155:                        p->in.right = r->in.left;
                    156:                        p->in.type = r->in.left->in.type;
                    157:                        r->in.left = p;
                    158:                        return(r);
                    159:                }
                    160:                return(p);
                    161: 
                    162:        case PVCONV:
                    163:        case PMCONV:
                    164:                if( p->in.right->in.op != ICON ) cerror( "bad conversion", 0);
                    165:                p->in.op = FREE;
                    166:                return( buildtree( o==PMCONV?MUL:DIV, p->in.left, p->in.right ) );
                    167: 
                    168:        case FLD:
                    169:                /* make sure that the second pass does not make the
                    170:                   descendant of a FLD operator into a doubly indexed OREG */
                    171: 
                    172:                if( p->in.left->in.op == UNARY MUL
                    173:                                && (r=p->in.left->in.left)->in.op == PCONV)
                    174:                        if( r->in.left->in.op == PLUS || r->in.left->in.op == MINUS ) 
                    175:                                if( ISPTR(r->in.type) ) {
                    176:                                        if( ISUNSIGNED(p->in.left->in.type) )
                    177:                                                p->in.left->in.type = UNSIGNED;
                    178:                                        else
                    179:                                                p->in.left->in.type = INT;
                    180:                                }
                    181:                break;
                    182:        case FORTCALL: /* arg must be FLOAT */
                    183:                if((r = p->in.right)->in.type != FLOAT)
                    184:                        p->in.right = clocal(makety(r, FLOAT, 0, FLOAT));
                    185:                return(p);
                    186:        }
                    187: 
                    188:        /* if both sides are FLOAT, so is the op */
                    189:        if(optype(o)!=LTYPE && p->in.left->in.type==DOUBLE &&
                    190:         (o==UNARY MINUS || optype(o)==BITYPE && p->in.right->in.type==DOUBLE)) {
                    191:                r = p->in.left;
                    192:                if(r->in.op==SCONV && r->in.left->in.type==FLOAT) {
                    193:                        if(optype(o)==BITYPE) {
                    194:                                r = p->in.right;
                    195:                                if(r->in.op==SCONV && r->in.left->in.type==FLOAT) {
                    196:                                        r->in.op = FREE;
                    197:                                        p->in.right = r->in.left;
                    198:                                } else if(r->in.op==FCON)
                    199:                                        r->in.type = FLOAT;
                    200:                                else
                    201:                                        return(p);
                    202:                        }
                    203:                        r = p->in.left;
                    204:                        p->in.left = r->in.left;
                    205:                } else if(optype(o)==BITYPE && r->in.op==FCON) {
                    206:                        r = p->in.right;
                    207:                        if(!(r->in.op==SCONV && r->in.left->in.type==FLOAT))
                    208:                                return(p);
                    209:                        p->in.right = r->in.left;
                    210:                        p->in.left->in.type = FLOAT;
                    211:                } else
                    212:                        return(p);
                    213:                if(p->in.type==DOUBLE) {
                    214:                        p->in.type = FLOAT;
                    215:                        r->in.left = p;
                    216:                        return(r);
                    217:                } else {        /* usually logop */
                    218:                        r->in.op = FREE;
                    219:                        return(p);
                    220:                }
                    221:        }
                    222:        return(p);
                    223: }
                    224: 
                    225: andable( p ) NODE *p; {
                    226:        return(1);  /* all names can have & taken on them */
                    227:        }
                    228: 
                    229: cendarg(){ /* at the end of the arguments of a ftn, set the automatic offset */
                    230:        autooff = AUTOINIT;
                    231:        }
                    232: 
                    233: cisreg( t ) TWORD t; { /* is an automatic variable of type t OK for a register variable */
                    234: 
                    235:        if( t==INT || t==UNSIGNED || t==LONG || t==ULONG        /* tbl */
                    236: #ifdef REG_CHAR
                    237:                || t==CHAR || t==UCHAR || t==SHORT || t==USHORT         /* tbl */
                    238: #endif
                    239:                || ISPTR(t) || t == FLOAT) return (1);          /* wnj */
                    240:        return(0);
                    241:        }
                    242: 
                    243: NODE *
                    244: offcon( off, t, d, s ) OFFSZ off; TWORD t; {
                    245: 
                    246:        /* return a node, for structure references, which is suitable for
                    247:           being added to a pointer of type t, in order to be off bits offset
                    248:           into a structure */
                    249: 
                    250:        register NODE *p;
                    251: 
                    252:        /* t, d, and s are the type, dimension offset, and sizeoffset */
                    253:        /* in general they  are necessary for offcon, but not on H'well */
                    254: 
                    255:        p = bcon(0);
                    256:        p->tn.lval = off/SZCHAR;
                    257:        return(p);
                    258: 
                    259:        }
                    260: 
                    261: 
                    262: static inwd    /* current bit offsed in word */;
                    263: static CONSZ word      /* word being built from fields */;
                    264: 
                    265: incode( p, sz ) register NODE *p; {
                    266: 
                    267:        /* generate initialization code for assigning a constant c
                    268:                to a field of width sz */
                    269:        /* we assume that the proper alignment has been obtained */
                    270:        /* inoff is updated to have the proper final value */
                    271:        /* we also assume sz  < SZINT */
                    272: 
                    273:        inwd += sz;
                    274:        if(inwd > SZINT) cerror("incode: field > int");
                    275:        word |= (p->tn.lval&((1L<<sz)-1)) << (SZINT-inwd);
                    276:        inoff += sz;
                    277:        if(inoff%SZINT == 0) {
                    278:                printf( "       .long   0x%X\n", word);
                    279:                word = inwd = 0;
                    280:                }
                    281:        }
                    282: 
                    283: fincode( d, sz ) double d; register int sz; {
                    284:        /*
                    285:         * output code to initialize space of size sz to the value d
                    286:         * the proper alignment has been obtained
                    287:         * inoff is updated to have the proper final value.
                    288:         */
                    289: 
                    290:        register struct sh4 {
                    291:                unsigned short sh[4];
                    292:        } *x;
                    293:        float f;
                    294: 
                    295:        if(sz == SZFLOAT) {     /* force rounding */
                    296:                f = d;
                    297:                d = f;
                    298:        }
                    299: 
                    300:        x = (struct sh4 *)&d;
                    301:        printf("        .long   0x%04x%04x", x->sh[0], x->sh[1]);
                    302:        if(sz == SZDOUBLE) {
                    303:                printf(", 0x%04x%04x", x->sh[2], x->sh[3]);
                    304:                printf(" # .double %.17g\n", d);
                    305:        } else
                    306:                printf(" # .float %.8g\n", d);
                    307:        inoff += sz;
                    308:        }
                    309: 
                    310: cinit( p, sz ) NODE *p; {
                    311:        NODE *l;
                    312: 
                    313:        /*
                    314:         * as a favor (?) to people who want to write
                    315:         *     int i = 9600/134.5;
                    316:         * we will, under the proper circumstances, do
                    317:         * a coersion here.
                    318:         */
                    319:        switch (p->in.type) {
                    320:        case INT:
                    321:        case UNSIGNED:
                    322:                l = p->in.left;
                    323:                if (l->in.op != SCONV ||
                    324:                    (l->in.left->tn.op != DCON && l->in.left->tn.op != FCON))
                    325:                        break;
                    326:                l->in.op = FREE;
                    327:                l = l->in.left;
                    328:                l->tn.lval = l->tn.op == DCON ? (long)(l->dpn.dval) :
                    329:                        (long)(l->fpn.fval);
                    330:                l->tn.rval = NONAME;
                    331:                l->tn.op = ICON;
                    332:                l->tn.type = INT;
                    333:                p->in.left = l;
                    334:                break;
                    335:        }
                    336:        /* arrange for the initialization of p into a space of
                    337:        size sz */
                    338:        /* the proper alignment has been opbtained */
                    339:        /* inoff is updated to have the proper final value */
                    340:        ecode( p );
                    341:        inoff += sz;
                    342:        }
                    343: 
                    344: vfdzero( n ){ /* define n bits of zeros in a vfd */
                    345: 
                    346:        if( n <= 0 ) return;
                    347: 
                    348:        inwd += n;
                    349:        inoff += n;
                    350:        if( inoff%ALINT ==0 ) {
                    351:                printf( "       .long   0x%X\n", word );
                    352:                word = inwd = 0;
                    353:                }
                    354:        }
                    355: 
                    356: char *
                    357: exname( p ) char *p; {
                    358:        /* make a name look like an external name in the local machine */
                    359: 
                    360: #ifndef FLEXNAMES
                    361:        static char text[NCHNAM+1];
                    362: #else
                    363:        static char text[BUFSIZ+1];
                    364: #endif
                    365: 
                    366:        register int i;
                    367: 
                    368:        text[0] = '_';
                    369: #ifndef FLEXNAMES
                    370:        for( i=1; *p&&i<NCHNAM; ++i )
                    371: #else
                    372:        for( i=1; *p; ++i )
                    373: #endif
                    374:                text[i] = *p++;
                    375: 
                    376:        text[i] = '\0';
                    377: #ifndef FLEXNAMES
                    378:        text[NCHNAM] = '\0';  /* truncate */
                    379: #endif
                    380: 
                    381:        return( text );
                    382:        }
                    383: 
                    384: ctype( type )TWORD type;{ /* map types which are not defined on the local machine */
                    385:        switch( BTYPE(type) ){
                    386: 
                    387:        case LONG:
                    388:                MODTYPE(type,INT);
                    389:                break;
                    390: 
                    391:        case ULONG:
                    392:                MODTYPE(type,UNSIGNED);
                    393:                }
                    394:        return( type );
                    395:        }
                    396: 
                    397: noinit() { /* curid is a variable which is defined but
                    398:        is not initialized (and not a function );
                    399:        This routine returns the stroage class for an uninitialized declaration */
                    400: 
                    401:        return(EXTERN);
                    402: 
                    403:        }
                    404: 
                    405: commdec( id ){ /* make a common declaration for id, if reasonable */
                    406:        register struct symtab *q;
                    407:        OFFSZ off, tsize();
                    408: 
                    409:        q = &stab[id];
                    410:        printf( "       .comm   %s,", exname( q->sname ) );
                    411:        off = tsize( q->stype, q->dimoff, q->sizoff );
                    412:        printf( "%d\n" /*CONFMT*/, off/SZCHAR );
                    413:        }
                    414: 
                    415: prtdcon(p)
                    416:        register NODE *p;
                    417: {
                    418:        register int o = p->in.op;
                    419:        int i;
                    420: 
                    421:        if (o != DCON && o != FCON)
                    422:                return;
                    423:        /*
                    424:         * Clobber constants of value zero so
                    425:         * we can generate more efficient code.
                    426:         */
                    427:        if ((o == DCON && p->dpn.dval == 0) ||
                    428:            (o == FCON && p->fpn.fval == 0)) {
                    429:                p->in.op = ICON;
                    430:                p->tn.rval = NONAME;
                    431:                return;
                    432:        }
                    433:        locctr(DATA);
                    434:        defalign(o == DCON ? ALDOUBLE : ALFLOAT);
                    435:        deflab(i = getlab());
                    436:        if (o == FCON)
                    437:                fincode(p->fpn.fval, SZFLOAT);
                    438:        else
                    439:                fincode(p->dpn.dval, SZDOUBLE);
                    440:        p->tn.lval = 0;
                    441:        p->tn.rval = -i;
                    442:        p->in.type = (o == DCON ? DOUBLE : FLOAT);
                    443:        p->in.op = NAME;
                    444: }
                    445: 
                    446: isitfloat( s ) char *s; {
                    447:        union cvt {
                    448:                double  d;
                    449:                int     n[2];
                    450:        } cvt;
                    451:        double atof();
                    452: 
                    453:        /* avoid floating point exception for double -> float conversions */
                    454:        dcon = cvt.d = atof(s);
                    455:        if( cvt.n[1] == 0 ){
                    456:                fcon = dcon;
                    457:                return( FCON );
                    458:                }
                    459:        return( DCON );
                    460:        }
                    461: 
                    462: ecode( p ) NODE *p; {
                    463: 
                    464:        /* walk the tree and write out the nodes.. */
                    465: 
                    466:        if( nerrors ) return;
                    467:        p2tree( p );
                    468:        p2compile( p );
                    469:        }
                    470: 
                    471: #ifndef ONEPASS
                    472: tlen(p) NODE *p; 
                    473: {
                    474:        switch(p->in.type) {
                    475:                case CHAR:
                    476:                case UCHAR:
                    477:                        return(1);
                    478:                        
                    479:                case SHORT:
                    480:                case USHORT:
                    481:                        return(2);
                    482:                        
                    483:                case DOUBLE:
                    484:                        return(8);
                    485:                        
                    486:                default:
                    487:                        return(4);
                    488:                }
                    489:        }
                    490: #endif

unix.superglobalmegacorp.com

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