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