|
|
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.2 (Berkeley) 7/26/85"; ! 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: * Evening ! 190: */ ! 191: long ! 192: leven(w) ! 193: register long w; ! 194: { ! 195: if (w < 0) ! 196: return (w & 0xfffffffe); ! 197: return ((w+1) & 0xfffffffe); ! 198: } ! 199: ! 200: #ifndef PC ! 201: int ! 202: even(w) ! 203: register int w; ! 204: { ! 205: return leven((long)w); ! 206: } ! 207: #endif ! 208: ! 209: /* ! 210: * Find the width of a type in bytes. ! 211: */ ! 212: width(np) ! 213: struct nl *np; ! 214: { ! 215: ! 216: return (lwidth(np)); ! 217: } ! 218: ! 219: long ! 220: lwidth(np) ! 221: struct nl *np; ! 222: { ! 223: register struct nl *p; ! 224: ! 225: p = np; ! 226: if (p == NIL) ! 227: return (0); ! 228: loop: ! 229: switch (p->class) { ! 230: default: ! 231: panic("wclass"); ! 232: case TYPE: ! 233: switch (nloff(p)) { ! 234: case TNIL: ! 235: return (2); ! 236: case TSTR: ! 237: case TSET: ! 238: panic("width"); ! 239: default: ! 240: p = p->type; ! 241: goto loop; ! 242: } ! 243: case ARRAY: ! 244: return (aryconst(p, 0)); ! 245: case PTR: ! 246: return ( sizeof ( int * ) ); ! 247: case FILET: ! 248: return ( sizeof(struct iorec) + lwidth( p -> type ) ); ! 249: case CRANGE: ! 250: p = p->type; ! 251: goto loop; ! 252: case RANGE: ! 253: if (p->type == nl+TDOUBLE) ! 254: #ifdef DEBUG ! 255: return (hp21mx ? 4 : 8); ! 256: #else ! 257: return (8); ! 258: #endif ! 259: case SCAL: ! 260: return (bytes(p->range[0], p->range[1])); ! 261: case SET: ! 262: setran(p->type); ! 263: /* ! 264: * Sets are some multiple of longs ! 265: */ ! 266: return roundup((int)((set.uprbp >> 3) + 1), ! 267: (long)(sizeof(long))); ! 268: case STR: ! 269: case RECORD: ! 270: return ( p->value[NL_OFFS] ); ! 271: } ! 272: } ! 273: ! 274: /* ! 275: * round up x to a multiple of y ! 276: * for computing offsets of aligned things. ! 277: * y had better be positive. ! 278: * rounding is in the direction of x. ! 279: */ ! 280: long ! 281: roundup( x , y ) ! 282: int x; ! 283: register long y; ! 284: { ! 285: ! 286: if ( y == 0 ) { ! 287: return x; ! 288: } ! 289: if ( x >= 0 ) { ! 290: return ( ( ( x + ( y - 1 ) ) / y ) * y ); ! 291: } else { ! 292: return ( ( ( x - ( y - 1 ) ) / y ) * y ); ! 293: } ! 294: } ! 295: ! 296: /* ! 297: * alignment of an object using the c alignment scheme ! 298: */ ! 299: int ! 300: align( np ) ! 301: struct nl *np; ! 302: { ! 303: register struct nl *p; ! 304: long elementalign; ! 305: ! 306: p = np; ! 307: if ( p == NIL ) { ! 308: return 0; ! 309: } ! 310: alignit: ! 311: switch ( p -> class ) { ! 312: default: ! 313: panic( "align" ); ! 314: case TYPE: ! 315: switch ( nloff( p ) ) { ! 316: case TNIL: ! 317: return A_POINT; ! 318: case TSTR: ! 319: return A_STRUCT; ! 320: case TSET: ! 321: return A_SET; ! 322: default: ! 323: p = p -> type; ! 324: goto alignit; ! 325: } ! 326: case ARRAY: ! 327: /* ! 328: * arrays are structures, since they can get ! 329: * assigned form/to as structure assignments. ! 330: * preserve internal alignment if it is greater. ! 331: */ ! 332: elementalign = align(p -> type); ! 333: return elementalign > A_STRUCT ? elementalign : A_STRUCT; ! 334: case PTR: ! 335: return A_POINT; ! 336: case FILET: ! 337: return A_FILET; ! 338: case CRANGE: ! 339: case RANGE: ! 340: if ( p -> type == nl+TDOUBLE ) { ! 341: return A_DOUBLE; ! 342: } ! 343: /* else, fall through */ ! 344: case SCAL: ! 345: switch ( bytes( p -> range[0] , p -> range[1] ) ) { ! 346: case 4: ! 347: return A_LONG; ! 348: case 2: ! 349: return A_SHORT; ! 350: case 1: ! 351: return A_CHAR; ! 352: default: ! 353: panic( "align: scal" ); ! 354: } ! 355: case SET: ! 356: return A_SET; ! 357: case STR: ! 358: /* ! 359: * arrays of chars are structs ! 360: */ ! 361: return A_STRUCT; ! 362: case RECORD: ! 363: /* ! 364: * the alignment of a record is in its align_info field ! 365: * why don't we use this for the rest of the namelist? ! 366: */ ! 367: return p -> align_info; ! 368: } ! 369: } ! 370: ! 371: #ifdef PC ! 372: /* ! 373: * output an alignment pseudo-op. ! 374: */ ! 375: aligndot(alignment) ! 376: int alignment; ! 377: #ifdef vax ! 378: { ! 379: switch (alignment) { ! 380: case 1: ! 381: return; ! 382: case 2: ! 383: putprintf(" .align 1", 0); ! 384: return; ! 385: default: ! 386: case 4: ! 387: putprintf(" .align 2", 0); ! 388: return; ! 389: } ! 390: } ! 391: #endif vax ! 392: #ifdef mc68000 ! 393: { ! 394: switch (alignment) { ! 395: case 1: ! 396: return; ! 397: default: ! 398: putprintf(" .even", 0); ! 399: return; ! 400: } ! 401: } ! 402: #endif mc68000 ! 403: #endif PC ! 404: ! 405: /* ! 406: * Return the width of an element ! 407: * of a n time subscripted np. ! 408: */ ! 409: long aryconst(np, n) ! 410: struct nl *np; ! 411: int n; ! 412: { ! 413: register struct nl *p; ! 414: long s, d; ! 415: ! 416: if ((p = np) == NIL) ! 417: return (NIL); ! 418: if (p->class != ARRAY) ! 419: panic("ary"); ! 420: /* ! 421: * If it is a conformant array, we cannot find the width from ! 422: * the type. ! 423: */ ! 424: if (p->chain->class == CRANGE) ! 425: return (NIL); ! 426: s = lwidth(p->type); ! 427: /* ! 428: * Arrays of anything but characters are word aligned. ! 429: */ ! 430: if (s & 1) ! 431: if (s != 1) ! 432: s++; ! 433: /* ! 434: * Skip the first n subscripts ! 435: */ ! 436: while (n >= 0) { ! 437: p = p->chain; ! 438: n--; ! 439: } ! 440: /* ! 441: * Sum across remaining subscripts. ! 442: */ ! 443: while (p != NIL) { ! 444: if (p->class != RANGE && p->class != SCAL) ! 445: panic("aryran"); ! 446: d = p->range[1] - p->range[0] + 1; ! 447: s *= d; ! 448: p = p->chain; ! 449: } ! 450: return (s); ! 451: } ! 452: ! 453: /* ! 454: * Find the lower bound of a set, and also its size in bits. ! 455: */ ! 456: setran(q) ! 457: struct nl *q; ! 458: { ! 459: register lb, ub; ! 460: register struct nl *p; ! 461: ! 462: p = q; ! 463: if (p == NIL) ! 464: return; ! 465: lb = p->range[0]; ! 466: ub = p->range[1]; ! 467: if (p->class != RANGE && p->class != SCAL) ! 468: panic("setran"); ! 469: set.lwrb = lb; ! 470: /* set.(upperbound prime) = number of bits - 1; */ ! 471: set.uprbp = ub-lb; ! 472: } ! 473: ! 474: /* ! 475: * Return the number of bytes required to hold an arithmetic quantity ! 476: */ ! 477: bytes(lb, ub) ! 478: long lb, ub; ! 479: { ! 480: ! 481: #ifndef DEBUG ! 482: if (lb < -32768 || ub > 32767) ! 483: return (4); ! 484: else if (lb < -128 || ub > 127) ! 485: return (2); ! 486: #else ! 487: if (!hp21mx && (lb < -32768 || ub > 32767)) ! 488: return (4); ! 489: if (lb < -128 || ub > 127) ! 490: return (2); ! 491: #endif ! 492: else ! 493: return (1); ! 494: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.