Annotation of researchv9/cmd/sun/pcc/local.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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