Annotation of researchv9/cmd/sun/pcc/local.c, revision 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.