Annotation of 43BSD/lib/pcc/local.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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