|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.