Annotation of 43BSDTahoe/ucb/pascal/src/var.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1980 Regents of the University of California.
                      3:  * All rights reserved.  The Berkeley software License Agreement
                      4:  * specifies the terms and conditions for redistribution.
                      5:  */
                      6: 
                      7: #ifndef lint
                      8: static char sccsid[] = "@(#)var.c      5.4 (Berkeley) 11/12/86";
                      9: #endif not lint
                     10: 
                     11: #include "whoami.h"
                     12: #include "0.h"
                     13: #include "objfmt.h"
                     14: #include "align.h"
                     15: #include "iorec.h"
                     16: #ifdef PC
                     17: #   include    "pc.h"
                     18: #endif PC
                     19: #include "tmps.h"
                     20: #include "tree_ty.h"
                     21: 
                     22: /*
                     23:  * Declare variables of a var part.  DPOFF1 is
                     24:  * the local variable storage for all prog/proc/func
                     25:  * modules aside from the block mark.  The total size
                     26:  * of all the local variables is entered into the
                     27:  * size array.
                     28:  */
                     29: /*ARGSUSED*/
                     30: varbeg( lineofyvar , r )
                     31:     int        lineofyvar;
                     32: {
                     33:     static bool        var_order = FALSE;
                     34:     static bool        var_seen = FALSE;
                     35: 
                     36: /* this allows for multiple declaration
                     37:  * parts except when the "standard"
                     38:  * option has been specified.
                     39:  * If routine segment is being compiled,
                     40:  * do level one processing.
                     41:  */
                     42: 
                     43: #ifndef PI1
                     44:        if (!progseen)
                     45:                level1();
                     46:        line = lineofyvar;
                     47:        if ( parts[ cbn ] & RPRT ) {
                     48:            if ( opt( 's' ) ) {
                     49:                standard();
                     50:                error("Variable declarations should precede routine declarations");
                     51:            } else {
                     52:                if ( !var_order ) {
                     53:                    var_order = TRUE;
                     54:                    warning();
                     55:                    error("Variable declarations should precede routine declarations");
                     56:                }
                     57:            }
                     58:        }
                     59:        if ( parts[ cbn ] & VPRT ) {
                     60:            if ( opt( 's' ) ) {
                     61:                standard();
                     62:                error("All variables should be declared in one var part");
                     63:            } else {
                     64:                if ( !var_seen ) {
                     65:                    var_seen = TRUE;
                     66:                    warning();
                     67:                    error("All variables should be declared in one var part");
                     68:                }
                     69:            }
                     70:        }
                     71:        parts[ cbn ] |= VPRT;
                     72: #endif
                     73:     /*
                     74:      *  #ifndef PI0
                     75:      *      sizes[cbn].om_max = sizes[cbn].curtmps.om_off = -DPOFF1;
                     76:      *  #endif
                     77:      */
                     78:        forechain = NIL;
                     79: #ifdef PI0
                     80:        send(REVVBEG);
                     81: #endif
                     82: }
                     83: 
                     84: var(vline, vidl, vtype)
                     85: #ifdef PI0
                     86:        int vline;
                     87:        struct tnode *vidl, *vtype;
                     88: {
                     89:        register struct nl *np;
                     90:        register struct tnode *vl;
                     91: 
                     92:        np = gtype(vtype);
                     93:        line = vline;
                     94:        /* why is this here? */
                     95:        for (vl = vidl; vl != TR_NIL; vl = vl->list_node.next) {
                     96:                }
                     97:        }
                     98:        send(REVVAR, vline, vidl, vtype);
                     99: }
                    100: #else
                    101:        int vline;
                    102:        register struct tnode *vidl;
                    103:        struct tnode *vtype;
                    104: {
                    105:        register struct nl *np;
                    106:        register struct om *op;
                    107:        long w;
                    108:        int o2;
                    109: #ifdef PC
                    110:        struct nl       *vp;
                    111: #endif
                    112: 
                    113:        np = gtype(vtype);
                    114:        line = vline;
                    115:        w = lwidth(np);
                    116:        op = &sizes[cbn];
                    117:        for (; vidl != TR_NIL; vidl = vidl->list_node.next) {
                    118: #              ifdef OBJ
                    119:                    op->curtmps.om_off =
                    120:                        roundup((int)(op->curtmps.om_off-w), (long)align(np));
                    121:                    o2 = op -> curtmps.om_off;
                    122: #              endif OBJ
                    123: #              ifdef PC
                    124:                    if ( cbn == 1 ) {
                    125:                                /*
                    126:                                 * global variables are not accessed off the fp
                    127:                                 * but rather by their names.
                    128:                                 */
                    129:                            o2 = 0;
                    130:                    } else {
                    131:                                /*
                    132:                                 * locals are aligned, too.
                    133:                                 */
                    134:                            op->curtmps.om_off =
                    135:                                roundup((int)(op->curtmps.om_off - w),
                    136:                                (long)align(np));
                    137:                            o2 = op -> curtmps.om_off;
                    138:                    }
                    139: #              endif PC
                    140: #              ifdef PC
                    141:                vp = enter(defnl((char *) vidl->list_node.list, VAR, np, o2));
                    142: #              else
                    143:                (void) enter(defnl((char *) vidl->list_node.list, VAR, np, o2));
                    144: #              endif
                    145:                if ( np != NLNIL && (np -> nl_flags & NFILES) ) {
                    146:                    dfiles[ cbn ] = TRUE;
                    147:                }
                    148: #              ifdef PC
                    149:                    if ( cbn == 1 ) {
                    150:                        putprintf( "    .data" , 0 );
                    151:                        aligndot(align(np));
                    152:                        putprintf( "    .comm   " , 1 );
                    153:                        putprintf( EXTFORMAT , 1 , (int) vidl->list_node.list );
                    154:                        putprintf( ",%d" , 0 , (int) w );
                    155:                        putprintf( "    .text" , 0 );
                    156:                        stabgvar( vp , w , line );
                    157:                        vp -> extra_flags |= NGLOBAL;
                    158:                    } else {
                    159:                        vp -> extra_flags |= NLOCAL;
                    160:                    }
                    161: #              endif PC
                    162:        }
                    163: #      ifdef PTREE
                    164:            {
                    165:                pPointer        *Vars;
                    166:                pPointer        Var = VarDecl( ovidl , vtype );
                    167: 
                    168:                pSeize( PorFHeader[ nesting ] );
                    169:                Vars = &( pDEF( PorFHeader[ nesting ] ).PorFVars );
                    170:                *Vars = ListAppend( *Vars , Var );
                    171:                pRelease( PorFHeader[ nesting ] );
                    172:            }
                    173: #      endif
                    174: }
                    175: #endif
                    176: 
                    177: varend()
                    178: {
                    179: 
                    180:        foredecl();
                    181: #ifndef PI0
                    182:        sizes[cbn].om_max = sizes[cbn].curtmps.om_off;
                    183: #else
                    184:        send(REVVEND);
                    185: #endif
                    186: }
                    187: 
                    188: /*
                    189:  * Find the width of a type in bytes.
                    190:  */
                    191: width(np)
                    192:        struct nl *np;
                    193: {
                    194: 
                    195:        return (lwidth(np));
                    196: }
                    197: 
                    198: long
                    199: lwidth(np)
                    200:        struct nl *np;
                    201: {
                    202:        register struct nl *p;
                    203: 
                    204:        p = np;
                    205:        if (p == NIL)
                    206:                return (0);
                    207: loop:
                    208:        switch (p->class) {
                    209:                default:
                    210:                        panic("wclass");
                    211:                case TYPE:
                    212:                        switch (nloff(p)) {
                    213:                                case TNIL:
                    214:                                        return (2);
                    215:                                case TSTR:
                    216:                                case TSET:
                    217:                                        panic("width");
                    218:                                default:
                    219:                                        p = p->type;
                    220:                                        goto loop;
                    221:                        }
                    222:                case ARRAY:
                    223:                        return (aryconst(p, 0));
                    224:                case PTR:
                    225:                        return ( sizeof ( int * ) );
                    226:                case FILET:
                    227:                        return ( sizeof(struct iorec) + lwidth( p -> type ) );
                    228:                case CRANGE:
                    229:                        p = p->type;
                    230:                        goto loop;
                    231:                case RANGE:
                    232:                        if (p->type == nl+TDOUBLE)
                    233: #ifdef DEBUG
                    234:                                return (hp21mx ? 4 : 8);
                    235: #else
                    236:                                return (8);
                    237: #endif
                    238:                case SCAL:
                    239:                        return (bytes(p->range[0], p->range[1]));
                    240:                case SET:
                    241:                        setran(p->type);
                    242:                        /*
                    243:                         * Sets are some multiple of longs
                    244:                         */
                    245:                        return roundup((int)((set.uprbp >> 3) + 1),
                    246:                                (long)(sizeof(long)));
                    247:                case STR:
                    248:                case RECORD:
                    249:                        return ( p->value[NL_OFFS] );
                    250:        }
                    251: }
                    252: 
                    253:     /*
                    254:      * round up x to a multiple of y
                    255:      * for computing offsets of aligned things.
                    256:      * y had better be positive.
                    257:      * rounding is in the direction of x.
                    258:      */
                    259: long
                    260: roundup( x , y )
                    261:     int                        x;
                    262:     register long      y;
                    263:     {
                    264:        
                    265:        if ( y == 0 ) {
                    266:            return x;
                    267:        }
                    268:        if ( x >= 0 ) {
                    269:                return ( ( ( x + ( y - 1 ) ) / y ) * y );
                    270:        } else {
                    271:                return ( ( ( x - ( y - 1 ) ) / y ) * y );
                    272:        }
                    273:     }
                    274: 
                    275:     /*
                    276:      * alignment of an object using the c alignment scheme
                    277:      */
                    278: int
                    279: align( np )
                    280:     struct nl  *np;
                    281:     {
                    282:        register struct nl *p;
                    283:        long elementalign;
                    284: 
                    285:        p = np;
                    286:        if ( p == NIL ) {
                    287:            return 0;
                    288:        }
                    289: alignit:
                    290:        switch ( p -> class ) {
                    291:            default:
                    292:                    panic( "align" );
                    293:            case TYPE:
                    294:                    switch ( nloff( p ) ) {
                    295:                        case TNIL:
                    296:                                return A_POINT;
                    297:                        case TSTR:
                    298:                                return A_STRUCT;
                    299:                        case TSET:
                    300:                                return A_SET;
                    301:                        default:
                    302:                                p = p -> type;
                    303:                                goto alignit;
                    304:                    }
                    305:            case ARRAY:
                    306:                        /*
                    307:                         * arrays are structures, since they can get
                    308:                         * assigned form/to as structure assignments.
                    309:                         * preserve internal alignment if it is greater.
                    310:                         */
                    311:                    elementalign = align(p -> type);
                    312:                    return elementalign > A_STRUCT ? elementalign : A_STRUCT;
                    313:            case PTR:
                    314:                    return A_POINT;
                    315:            case FILET:
                    316:                    return A_FILET;
                    317:            case CRANGE:
                    318:            case RANGE:
                    319:                    if ( p -> type == nl+TDOUBLE ) {
                    320:                        return A_DOUBLE;
                    321:                    }
                    322:                    /* else, fall through */
                    323:            case SCAL:
                    324:                    switch ( bytes( p -> range[0] , p -> range[1] ) ) {
                    325:                        case 4:
                    326:                            return A_LONG;
                    327:                        case 2:
                    328:                            return A_SHORT;
                    329:                        case 1:
                    330:                            return A_CHAR;
                    331:                        default:
                    332:                            panic( "align: scal" );
                    333:                    }
                    334:            case SET:
                    335:                    return A_SET;
                    336:            case STR:
                    337:                        /*
                    338:                         * arrays of chars are structs
                    339:                         */
                    340:                    return A_STRUCT;
                    341:            case RECORD:
                    342:                        /*
                    343:                         * the alignment of a record is in its align_info field
                    344:                         * why don't we use this for the rest of the namelist?
                    345:                         */
                    346:                    return p -> align_info;
                    347:        }
                    348:     }
                    349: 
                    350: #ifdef PC
                    351:     /*
                    352:      * output an alignment pseudo-op.
                    353:      */
                    354: aligndot(alignment)
                    355:     int        alignment;
                    356: #if defined(vax) || defined(tahoe)
                    357: {
                    358:     switch (alignment) {
                    359:        case 1:
                    360:            return;
                    361:        case 2:
                    362:            putprintf(" .align 1", 0);
                    363:            return;
                    364:        default:
                    365:        case 4:
                    366:            putprintf(" .align 2", 0);
                    367:            return;
                    368:     }
                    369: }
                    370: #endif vax || tahoe
                    371: #ifdef mc68000
                    372: {
                    373:     switch (alignment) {
                    374:        case 1:
                    375:            return;
                    376:        default:
                    377:            putprintf(" .even", 0);
                    378:            return;
                    379:     }
                    380: }
                    381: #endif mc68000
                    382: #endif PC
                    383:     
                    384: /*
                    385:  * Return the width of an element
                    386:  * of a n time subscripted np.
                    387:  */
                    388: long aryconst(np, n)
                    389:        struct nl *np;
                    390:        int n;
                    391: {
                    392:        register struct nl *p;
                    393:        long s, d;
                    394: 
                    395:        if ((p = np) == NIL)
                    396:                return (NIL);
                    397:        if (p->class != ARRAY)
                    398:                panic("ary");
                    399:        /*
                    400:         * If it is a conformant array, we cannot find the width from
                    401:         * the type.
                    402:         */
                    403:        if (p->chain->class == CRANGE)
                    404:                return (NIL);
                    405:        s = lwidth(p->type);
                    406:        /*
                    407:         * Arrays of anything but characters are word aligned.
                    408:         */
                    409:        if (s & 1)
                    410:                if (s != 1)
                    411:                        s++;
                    412:        /*
                    413:         * Skip the first n subscripts
                    414:         */
                    415:        while (n >= 0) {
                    416:                p = p->chain;
                    417:                n--;
                    418:        }
                    419:        /*
                    420:         * Sum across remaining subscripts.
                    421:         */
                    422:        while (p != NIL) {
                    423:                if (p->class != RANGE && p->class != SCAL)
                    424:                        panic("aryran");
                    425:                d = p->range[1] - p->range[0] + 1;
                    426:                s *= d;
                    427:                p = p->chain;
                    428:        }
                    429:        return (s);
                    430: }
                    431: 
                    432: /*
                    433:  * Find the lower bound of a set, and also its size in bits.
                    434:  */
                    435: setran(q)
                    436:        struct nl *q;
                    437: {
                    438:        register lb, ub;
                    439:        register struct nl *p;
                    440: 
                    441:        p = q;
                    442:        if (p == NIL)
                    443:                return;
                    444:        lb = p->range[0];
                    445:        ub = p->range[1];
                    446:        if (p->class != RANGE && p->class != SCAL)
                    447:                panic("setran");
                    448:        set.lwrb = lb;
                    449:        /* set.(upperbound prime) = number of bits - 1; */
                    450:        set.uprbp = ub-lb;
                    451: }
                    452: 
                    453: /*
                    454:  * Return the number of bytes required to hold an arithmetic quantity
                    455:  */
                    456: bytes(lb, ub)
                    457:        long lb, ub;
                    458: {
                    459: 
                    460: #ifndef DEBUG
                    461:        if (lb < -32768 || ub > 32767)
                    462:                return (4);
                    463:        else if (lb < -128 || ub > 127)
                    464:                return (2);
                    465: #else
                    466:        if (!hp21mx && (lb < -32768 || ub > 32767))
                    467:                return (4);
                    468:        if (lb < -128 || ub > 127)
                    469:                return (2);
                    470: #endif
                    471:        else
                    472:                return (1);
                    473: }

unix.superglobalmegacorp.com

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