Annotation of researchv10dc/cmd/pcc1/pcc/local.c, revision 1.1.1.1

1.1       root        1: static char *sccsid ="%W% (Berkeley) %G%";
                      2: # include "mfile1"
                      3: 
                      4: /*     this file contains code which is dependent on the target machine */
                      5: 
                      6: NODE *
                      7: cast( p, t ) register NODE *p; TWORD t; {
                      8:        /* cast node p to type t */
                      9: 
                     10:        p = buildtree( CAST, block( NAME, NIL, NIL, t, 0, (int)t ), p );
                     11:        p->in.left->in.op = FREE;
                     12:        p->in.op = FREE;
                     13:        return( p->in.right );
                     14:        }
                     15: 
                     16: NODE *
                     17: clocal(p) NODE *p; {
                     18: 
                     19:        /* this is called to do local transformations on
                     20:           an expression tree preparitory to its being
                     21:           written out in intermediate code.
                     22:        */
                     23: 
                     24:        /* the major essential job is rewriting the
                     25:           automatic variables and arguments in terms of
                     26:           REG and OREG nodes */
                     27:        /* conversion ops which are not necessary are also clobbered here */
                     28:        /* in addition, any special features (such as rewriting
                     29:           exclusive or) are easily handled here as well */
                     30: 
                     31:        register struct symtab *q;
                     32:        register NODE *r;
                     33:        register o;
                     34:        register m, ml;
                     35: 
                     36:        switch( o = p->in.op ){
                     37: 
                     38:        case NAME:
                     39:                if( p->tn.rval < 0 ) { /* already processed; ignore... */
                     40:                        return(p);
                     41:                        }
                     42:                q = &stab[p->tn.rval];
                     43:                switch( q->sclass ){
                     44: 
                     45:                case AUTO:
                     46:                case PARAM:
                     47:                        /* fake up a structure reference */
                     48:                        r = block( REG, NIL, NIL, PTR+STRTY, 0, 0 );
                     49:                        r->tn.lval = 0;
                     50:                        r->tn.rval = (q->sclass==AUTO?STKREG:ARGREG);
                     51:                        p = stref( block( STREF, r, p, 0, 0, 0 ) );
                     52:                        break;
                     53: 
                     54:                case ULABEL:
                     55:                case LABEL:
                     56:                case STATIC:
                     57:                        if( q->slevel == 0 ) break;
                     58:                        p->tn.lval = 0;
                     59:                        p->tn.rval = -q->offset;
                     60:                        break;
                     61: 
                     62:                case REGISTER:
                     63:                        p->in.op = REG;
                     64:                        p->tn.lval = 0;
                     65:                        p->tn.rval = q->offset;
                     66:                        break;
                     67: 
                     68:                        }
                     69:                break;
                     70: 
                     71:        case PCONV:
                     72:                /* do pointer conversions for char and longs */
                     73:                ml = p->in.left->in.type;
                     74:                if( ( ml==CHAR || ml==UCHAR || ml==SHORT || ml==USHORT ) && p->in.left->in.op != ICON ) break;
                     75: 
                     76:                /* pointers all have the same representation; the type is inherited */
                     77: 
                     78:        inherit:
                     79:                p->in.left->in.type = p->in.type;
                     80:                p->in.left->fn.cdim = p->fn.cdim;
                     81:                p->in.left->fn.csiz = p->fn.csiz;
                     82:                p->in.op = FREE;
                     83:                return( p->in.left );
                     84: 
                     85:        case SCONV:
                     86:                m = (p->in.type == FLOAT || p->in.type == DOUBLE );
                     87:                ml = (p->in.left->in.type == FLOAT || p->in.left->in.type == DOUBLE );
                     88:                if( m != ml ) break;
                     89: 
                     90:                /* now, look for conversions downwards */
                     91: 
                     92:                m = p->in.type;
                     93:                ml = p->in.left->in.type;
                     94:                if( p->in.left->in.op == ICON ){ /* simulate the conversion here */
                     95:                        CONSZ val;
                     96:                        val = p->in.left->tn.lval;
                     97:                        switch( m ){
                     98:                        case CHAR:
                     99:                                p->in.left->tn.lval = (char) val;
                    100:                                break;
                    101:                        case UCHAR:
                    102:                                p->in.left->tn.lval = val & 0XFF;
                    103:                                break;
                    104:                        case USHORT:
                    105:                                p->in.left->tn.lval = val & 0XFFFFL;
                    106:                                break;
                    107:                        case SHORT:
                    108:                                p->in.left->tn.lval = (short)val;
                    109:                                break;
                    110:                        case UNSIGNED:
                    111:                                p->in.left->tn.lval = val & 0xFFFFFFFFL;
                    112:                                break;
                    113:                        case INT:
                    114:                                p->in.left->tn.lval = (int)val;
                    115:                                break;
                    116:                                }
                    117:                        p->in.left->in.type = m;
                    118:                        }
                    119:                else {
                    120:                        /* meaningful ones are conversion of int to char, int to short,
                    121:                           and short to char, and unsigned version of them */
                    122:                        if( m==CHAR || m==UCHAR ){
                    123:                                if( ml!=CHAR && ml!= UCHAR ) break;
                    124:                                }
                    125:                        else if( m==SHORT || m==USHORT ){
                    126:                                if( ml!=CHAR && ml!=UCHAR && ml!=SHORT && ml!=USHORT ) break;
                    127:                                }
                    128:                        }
                    129: 
                    130:                /* clobber conversion */
                    131:                if( tlen(p) == tlen(p->in.left) ) goto inherit;
                    132:                p->in.op = FREE;
                    133:                return( p->in.left );  /* conversion gets clobbered */
                    134: 
                    135:        case PVCONV:
                    136:        case PMCONV:
                    137:                if( p->in.right->in.op != ICON ) cerror( "bad conversion", 0);
                    138:                p->in.op = FREE;
                    139:                return( buildtree( o==PMCONV?MUL:DIV, p->in.left, p->in.right ) );
                    140: 
                    141:        case RS:
                    142:        case ASG RS:
                    143:                /* convert >> to << with negative shift count */
                    144:                /* only if type of left operand is not unsigned */
                    145: 
                    146:                if( ISUNSIGNED(p->in.left->in.type) ) break;
                    147:                p->in.right = buildtree( UNARY MINUS, p->in.right, NIL );
                    148:                if( p->in.op == RS ) p->in.op = LS;
                    149:                else p->in.op = ASG LS;
                    150:                break;
                    151: 
                    152:        case FLD:
                    153:                /* make sure that the second pass does not make the
                    154:                   descendant of a FLD operator into a doubly indexed OREG */
                    155: 
                    156:                if( p->in.left->in.op == UNARY MUL
                    157:                                && (r=p->in.left->in.left)->in.op == PCONV)
                    158:                        if( r->in.left->in.op == PLUS || r->in.left->in.op == MINUS ) 
                    159:                                if( ISPTR(r->in.type) ) {
                    160:                                        if( ISUNSIGNED(p->in.left->in.type) )
                    161:                                                p->in.left->in.type = UCHAR;
                    162:                                        else
                    163:                                                p->in.left->in.type = CHAR;
                    164:                                }
                    165:                break;
                    166:                }
                    167: 
                    168:        return(p);
                    169:        }
                    170: 
                    171: andable( p ) NODE *p; {
                    172:        return(1);  /* all names can have & taken on them */
                    173:        }
                    174: 
                    175: cendarg(){ /* at the end of the arguments of a ftn, set the automatic offset */
                    176:        autooff = AUTOINIT;
                    177:        }
                    178: 
                    179: cisreg( t ) TWORD t; { /* is an automatic variable of type t OK for a register variable */
                    180: 
                    181: #ifdef TRUST_REG_CHAR_AND_REG_SHORT
                    182:        if( t==INT || t==UNSIGNED || t==LONG || t==ULONG        /* tbl */
                    183:                || t==CHAR || t==UCHAR || t==SHORT              /* tbl */
                    184:                || t==USHORT || ISPTR(t)) return(1);            /* tbl */
                    185: #else
                    186:        if( t==INT || t==UNSIGNED || t==LONG || t==ULONG        /* wnj */
                    187:                || ISPTR(t)) return (1);                        /* wnj */
                    188: #endif
                    189:        return(0);
                    190:        }
                    191: 
                    192: NODE *
                    193: offcon( off, t, d, s ) OFFSZ off; TWORD t; {
                    194: 
                    195:        /* return a node, for structure references, which is suitable for
                    196:           being added to a pointer of type t, in order to be off bits offset
                    197:           into a structure */
                    198: 
                    199:        register NODE *p;
                    200: 
                    201:        /* t, d, and s are the type, dimension offset, and sizeoffset */
                    202:        /* in general they  are necessary for offcon, but not on H'well */
                    203: 
                    204:        p = bcon(0);
                    205:        p->tn.lval = off/SZCHAR;
                    206:        return(p);
                    207: 
                    208:        }
                    209: 
                    210: 
                    211: static inwd    /* current bit offsed in word */;
                    212: static word    /* word being built from fields */;
                    213: 
                    214: incode( p, sz ) register NODE *p; {
                    215: 
                    216:        /* generate initialization code for assigning a constant c
                    217:                to a field of width sz */
                    218:        /* we assume that the proper alignment has been obtained */
                    219:        /* inoff is updated to have the proper final value */
                    220:        /* we also assume sz  < SZINT */
                    221: 
                    222:        if((sz+inwd) > SZINT) cerror("incode: field > int");
                    223:        word |= ((unsigned)(p->tn.lval<<(32-sz))) >> (32-sz-inwd);
                    224:        inwd += sz;
                    225:        inoff += sz;
                    226:        if(inoff%SZINT == 0) {
                    227:                printf( "       .long   0x%x\n", word);
                    228:                word = inwd = 0;
                    229:                }
                    230:        }
                    231: 
                    232: fincode( d, sz ) double d; {
                    233:        /* output code to initialize space of size sz to the value d */
                    234:        /* the proper alignment has been obtained */
                    235:        /* inoff is updated to have the proper final value */
                    236:        /* on the target machine, write it out in hex! (ark) */
                    237: 
                    238: 
                    239: #ifdef vax
                    240:        if (sz == SZDOUBLE)
                    241:                printf ("       .long   0x%lx,0x%lx\n", d);
                    242:        else
                    243:                printf ("       .long   0x%lx\n", d);
                    244: #else
                    245:        printf("        %s      0%c%.20e\n", sz == SZDOUBLE ? ".double" : ".float",
                    246:                sz == SZDOUBLE ? 'd' : 'f', d);
                    247: #endif
                    248:        inoff += sz;
                    249:        }
                    250: 
                    251: cinit( p, sz ) NODE *p; {
                    252:        /* arrange for the initialization of p into a space of
                    253:        size sz */
                    254:        /* the proper alignment has been opbtained */
                    255:        /* inoff is updated to have the proper final value */
                    256:        ecode( p );
                    257:        inoff += sz;
                    258:        }
                    259: 
                    260: vfdzero( n ){ /* define n bits of zeros in a vfd */
                    261: 
                    262:        if( n <= 0 ) return;
                    263: 
                    264:        inwd += n;
                    265:        inoff += n;
                    266:        if( inoff%ALINT ==0 ) {
                    267:                printf( "       .long   0x%x\n", word );
                    268:                word = inwd = 0;
                    269:                }
                    270:        }
                    271: 
                    272: char *
                    273: exname( p ) char *p; {
                    274:        /* make a name look like an external name in the local machine */
                    275: 
                    276: #ifndef FLEXNAMES
                    277:        static char text[NCHNAM+1];
                    278: #else
                    279:        static char text[BUFSIZ+1];
                    280: #endif
                    281: 
                    282:        register i;
                    283: 
                    284:        text[0] = '_';
                    285: #ifndef FLEXNAMES
                    286:        for( i=1; *p&&i<NCHNAM; ++i ){
                    287: #else
                    288:        for( i=1; *p; ++i ){
                    289: #endif
                    290:                text[i] = *p++;
                    291:                }
                    292: 
                    293:        text[i] = '\0';
                    294: #ifndef FLEXNAMES
                    295:        text[NCHNAM] = '\0';  /* truncate */
                    296: #endif
                    297: 
                    298:        return( text );
                    299:        }
                    300: 
                    301: ctype( type ){ /* map types which are not defined on the local machine */
                    302:        switch( BTYPE(type) ){
                    303: 
                    304:        case LONG:
                    305:                MODTYPE(type,INT);
                    306:                break;
                    307: 
                    308:        case ULONG:
                    309:                MODTYPE(type,UNSIGNED);
                    310:                }
                    311:        return( type );
                    312:        }
                    313: 
                    314: noinit( t ) { /* curid is a variable which is defined but
                    315:        is not initialized (and not a function );
                    316:        This routine returns the stroage class for an uninitialized declaration */
                    317: 
                    318:        return(EXTERN);
                    319: 
                    320:        }
                    321: 
                    322: commdec( id ){ /* make a common declaration for id, if reasonable */
                    323:        register struct symtab *q;
                    324:        OFFSZ off, tsize();
                    325: 
                    326:        q = &stab[id];
                    327:        printf( "       .comm   %s,", exname( q->sname ) );
                    328:        off = tsize( q->stype, q->dimoff, q->sizoff );
                    329:        printf( CONFMT, off/SZCHAR );
                    330:        printf( "\n" );
                    331:        }
                    332: 
                    333: isitlong( cb, ce ){ /* is lastcon to be long or short */
                    334:        /* cb is the first character of the representation, ce the last */
                    335: 
                    336:        if( ce == 'l' || ce == 'L' ||
                    337:                lastcon >= (1L << (SZINT-1) ) ) return (1);
                    338:        return(0);
                    339:        }
                    340: 
                    341: 
                    342: isitfloat( s ) char *s; {
                    343:        double atof();
                    344:        dcon = atof(s);
                    345:        return( FCON );
                    346:        }
                    347: 
                    348: ecode( p ) NODE *p; {
                    349: 
                    350:        /* walk the tree and write out the nodes.. */
                    351: 
                    352:        if( nerrors ) return;
                    353:        p2tree( p );
                    354:        p2compile( p );
                    355:        }
                    356:        
                    357: #include <sys/types.h>
                    358: #include <a.out.h>
                    359: #include <stab.h>
                    360: extern int ddebug;
                    361: extern int gdebug;
                    362: 
                    363: fixarg(p)
                    364: struct symtab *p; {
                    365:                pstab(p->sname, N_PSYM);
                    366:                if (gdebug) printf("0,%d,%d\n", p->stype, argoff/SZCHAR);
                    367:                poffs(p);
                    368: }
                    369: int    stabLCSYM;
                    370: 
                    371: outstab(p)
                    372: struct symtab *p; {
                    373:        register TWORD ptype;
                    374:        register char *pname;
                    375:        register char pclass;
                    376:        register int poffset;
                    377: 
                    378:        if (!gdebug) return;
                    379: 
                    380:        ptype = p->stype;
                    381:        pname = p->sname;
                    382:        pclass = p->sclass;
                    383:        poffset = p->offset;
                    384: 
                    385:        if (ISFTN(ptype)) {
                    386:                return;
                    387:        }
                    388:        
                    389:        switch (pclass) {
                    390:        
                    391:        case AUTO:
                    392:                pstab(pname, N_LSYM);
                    393:                printf("0,%d,%d\n", ptype, (-poffset)/SZCHAR);
                    394:                poffs(p);
                    395:                return;
                    396:        
                    397:        case EXTDEF:
                    398:        case EXTERN:
                    399:                pstab(pname, N_GSYM);
                    400:                printf("0,%d,0\n", ptype);
                    401:                poffs(p);
                    402:                return;
                    403:                        
                    404:        case STATIC:
                    405: #ifdef LCOMM
                    406:                /* stabLCSYM is 1 during nidcl so we can get stab type right */
                    407:                pstab(pname, stabLCSYM ? N_LCSYM : N_STSYM);
                    408: #else
                    409:                pstab(pname, N_STSYM);
                    410: #endif
                    411:                if (p->slevel > 1) {
                    412:                        printf("0,%d,L%d\n", ptype, poffset);
                    413:                } else {
                    414:                        printf("0,%d,%s\n", ptype, exname(pname));
                    415:                }
                    416:                poffs(p);
                    417:                return;
                    418:        
                    419:        case REGISTER:
                    420:                pstab(pname, N_RSYM);
                    421:                printf("0,%d,%d\n", ptype, poffset);
                    422:                poffs(p);
                    423:                return;
                    424:        
                    425:        case MOS:
                    426:        case MOU:
                    427:                pstab(pname, N_SSYM);
                    428:                printf("0,%d,%d\n", ptype, poffset/SZCHAR);
                    429:                poffs(p);
                    430:                return;
                    431:        
                    432:        case PARAM:
                    433:                /* parameter stab entries are processed in dclargs() */
                    434:                return;
                    435:        
                    436:        default:
                    437: #ifndef FLEXNAMES
                    438:                if (ddebug) printf("    No .stab for %.8s\n", pname);
                    439: #else
                    440:                if (ddebug) printf("    No .stab for %s\n", pname);
                    441: #endif
                    442:                
                    443:        }
                    444: }
                    445: 
                    446: pstab(name, type)
                    447: char *name;
                    448: int type; {
                    449:        register int i;
                    450:        register char c;
                    451:        if (!gdebug) return;
                    452:        /* locctr(PROG);  /* .stabs must appear in .text for c2 */
                    453: #ifdef ASSTRINGS
                    454:        if ( name[0] == '\0')
                    455:                printf("\t.stabn\t");
                    456:        else
                    457: #ifndef FLEXNAMES
                    458:                printf("\t.stabs\t\"%.8s\", ", name);
                    459: #else
                    460:                printf("\t.stabs\t\"%s\", ", name);
                    461: #endif
                    462: #else
                    463:        printf("        .stab   ");
                    464:        for(i=0; i<8; i++) 
                    465:                if (c = name[i]) printf("'%c,", c);
                    466:                else printf("0,");
                    467: #endif
                    468:        printf("0%o,", type);
                    469: }
                    470: 
                    471: #ifdef STABDOT
                    472: pstabdot(type, value)
                    473:        int     type;
                    474:        int     value;
                    475: {
                    476:        if ( ! gdebug) return;
                    477:        /* locctr(PROG);  /* .stabs must appear in .text for c2 */
                    478:        printf("\t.stabd\t");
                    479:        printf("0%o,0,0%o\n",type, value);
                    480: }
                    481: #endif
                    482: 
                    483: poffs(p)
                    484: register struct symtab *p; {
                    485:        int s;
                    486:        if (!gdebug) return;
                    487:        if ((s = dimtab[p->sizoff]/SZCHAR) > 1) {
                    488:                pstab(p->sname, N_LENG);
                    489:                printf("1,0,%d\n", s);
                    490:        }
                    491: }
                    492: 
                    493: extern char NULLNAME[8];
                    494: extern int  labelno;
                    495: extern int  fdefflag;
                    496: 
                    497: psline() {
                    498:        static int lastlineno;
                    499:        register char *cp, *cq;
                    500:        register int i;
                    501:        
                    502:        if (!gdebug) return;
                    503: 
                    504:        cq = ititle;
                    505:        cp = ftitle;
                    506: 
                    507:        while ( *cq ) if ( *cp++ != *cq++ ) goto neq;
                    508:        if ( *cp == '\0' ) goto eq;
                    509:        
                    510: neq:   for (i=0; i<100; i++)
                    511:                ititle[i] = '\0';
                    512:        cp = ftitle;
                    513:        cq = ititle;
                    514:        while ( *cp )  
                    515:                *cq++ = *cp++;
                    516:        *cq = '\0';
                    517:        *--cq = '\0';
                    518: #ifndef FLEXNAMES
                    519:        for ( cp = ititle+1; *(cp-1); cp += 8 ) {
                    520:                pstab(cp, N_SOL);
                    521:                if (gdebug) printf("0,0,LL%d\n", labelno);
                    522:                }
                    523: #else
                    524:        pstab(ititle+1, N_SOL);
                    525:        if (gdebug) printf("0,0,LL%d\n", labelno);
                    526: #endif
                    527:        *cq = '"';
                    528:        printf("LL%d:\n", labelno++);
                    529: 
                    530: eq:    if (lineno == lastlineno) return;
                    531:        lastlineno = lineno;
                    532: 
                    533:        if (fdefflag) {
                    534: #ifdef STABDOT
                    535:                pstabdot(N_SLINE, lineno);
                    536: #else
                    537:                pstab(NULLNAME, N_SLINE);
                    538:                printf("0,%d,LL%d\n", lineno, labelno);
                    539:                printf("LL%d:\n", labelno++);
                    540: #endif
                    541:                }
                    542:        }
                    543:        
                    544: plcstab(level) {
                    545:        if (!gdebug) return;
                    546: #ifdef STABDOT
                    547:        pstabdot(N_LBRAC, level);
                    548: #else
                    549:        pstab(NULLNAME, N_LBRAC);
                    550:        printf("0,%d,LL%d\n", level, labelno);
                    551:        printf("LL%d:\n", labelno++);
                    552: #endif
                    553:        }
                    554:        
                    555: prcstab(level) {
                    556:        if (!gdebug) return;
                    557: #ifdef STABDOT
                    558:        pstabdot(N_RBRAC, level);
                    559: #else
                    560:        pstab(NULLNAME, N_RBRAC);
                    561:        printf("0,%d,LL%d\n", level, labelno);
                    562:        printf("LL%d:\n", labelno++);
                    563: #endif
                    564:        }
                    565:        
                    566: pfstab(sname) 
                    567: char *sname; {
                    568:        if (!gdebug) return;
                    569:        pstab(sname, N_FUN);
                    570: #ifndef FLEXNAMES
                    571:        printf("0,%d,_%.7s\n", lineno, sname);
                    572: #else
                    573:        printf("0,%d,_%s\n", lineno, sname);
                    574: #endif
                    575: }
                    576: 
                    577: #ifndef ONEPASS
                    578: tlen(p) NODE *p; 
                    579: {
                    580:        switch(p->in.type) {
                    581:                case CHAR:
                    582:                case UCHAR:
                    583:                        return(1);
                    584:                        
                    585:                case SHORT:
                    586:                case USHORT:
                    587:                        return(2);
                    588:                        
                    589:                case DOUBLE:
                    590:                        return(8);
                    591:                        
                    592:                default:
                    593:                        return(4);
                    594:                }
                    595:        }
                    596: #endif

unix.superglobalmegacorp.com

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