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