1781Speter /* Copyright (c) 1979 Regents of the University of California */ 2781Speter 3*3836Speter static char sccsid[] = "@(#)var.c 1.9 06/01/81"; 4781Speter 5781Speter #include "whoami.h" 6781Speter #include "0.h" 7781Speter #include "align.h" 82075Smckusic #include "iorec.h" 9781Speter #ifdef PC 10781Speter # include "pc.h" 11781Speter # include "pcops.h" 12781Speter #endif PC 13781Speter 14781Speter /* 15781Speter * Declare variables of a var part. DPOFF1 is 16781Speter * the local variable storage for all prog/proc/func 17781Speter * modules aside from the block mark. The total size 18781Speter * of all the local variables is entered into the 19781Speter * size array. 20781Speter */ 21781Speter varbeg() 22781Speter { 23781Speter 24837Speter /* this allows for multiple declaration 25781Speter * parts except when the "standard" 26781Speter * option has been specified. 27781Speter * If routine segment is being compiled, 28781Speter * do level one processing. 29781Speter */ 30781Speter 31781Speter #ifndef PI1 32837Speter if (!progseen) 33837Speter level1(); 34837Speter if ( parts[ cbn ] & RPRT ) { 35837Speter if ( opt( 's' ) ) { 36781Speter standard(); 37837Speter } else { 38837Speter warning(); 39837Speter } 40837Speter error("Variable declarations should precede routine declarations"); 41781Speter } 42837Speter if ( parts[ cbn ] & VPRT ) { 43837Speter if ( opt( 's' ) ) { 44837Speter standard(); 45837Speter } else { 46837Speter warning(); 47837Speter } 48837Speter error("All variables should be declared in one var part"); 49837Speter } 50837Speter parts[ cbn ] |= VPRT; 51781Speter #endif 52781Speter /* 53781Speter * #ifndef PI0 543229Smckusic * sizes[cbn].om_max = sizes[cbn].curtmps.om_off = -DPOFF1; 55781Speter * #endif 56781Speter */ 57781Speter forechain = NIL; 58781Speter #ifdef PI0 59781Speter send(REVVBEG); 60781Speter #endif 61781Speter } 62781Speter 63781Speter var(vline, vidl, vtype) 64781Speter #ifdef PI0 65781Speter int vline, *vidl, *vtype; 66781Speter { 67781Speter register struct nl *np; 68781Speter register int *vl; 69781Speter 70781Speter np = gtype(vtype); 71781Speter line = vline; 72781Speter for (vl = vidl; vl != NIL; vl = vl[2]) { 73781Speter } 74781Speter } 75781Speter send(REVVAR, vline, vidl, vtype); 76781Speter } 77781Speter #else 78781Speter int vline; 79781Speter register int *vidl; 80781Speter int *vtype; 81781Speter { 82781Speter register struct nl *np; 83781Speter register struct om *op; 84781Speter long w; 85781Speter int o2; 86781Speter int *ovidl = vidl; 87*3836Speter struct nl *vp; 88781Speter 89781Speter np = gtype(vtype); 90781Speter line = vline; 91781Speter /* 92781Speter * widths are evened out 93781Speter */ 94781Speter w = (lwidth(np) + 1) &~ 1; 95781Speter op = &sizes[cbn]; 96781Speter for (; vidl != NIL; vidl = vidl[2]) { 97781Speter # ifdef OBJ 983235Smckusic op->curtmps.om_off = 993235Smckusic roundup((int)(op->curtmps.om_off-w), (long)align(np)); 1003235Smckusic o2 = op -> curtmps.om_off; 101781Speter # endif OBJ 102781Speter # ifdef PC 103781Speter if ( cbn == 1 ) { 104781Speter /* 105781Speter * global variables are not accessed off the fp 106781Speter * but rather by their names. 107781Speter */ 108781Speter o2 = 0; 109781Speter } else { 110781Speter /* 111781Speter * locals are aligned, too. 112781Speter */ 1133229Smckusic op->curtmps.om_off = 1143229Smckusic roundup((int)(op->curtmps.om_off - w), 1153082Smckusic (long)align(np)); 1163229Smckusic o2 = op -> curtmps.om_off; 117781Speter } 118781Speter # endif PC 119*3836Speter vp = enter(defnl(vidl[1], VAR, np, o2)); 120781Speter if ( np -> nl_flags & NFILES ) { 121781Speter dfiles[ cbn ] = TRUE; 122781Speter } 123781Speter # ifdef PC 124781Speter if ( cbn == 1 ) { 125781Speter putprintf( " .data" , 0 ); 126781Speter putprintf( " .comm " , 1 ); 127781Speter putprintf( EXTFORMAT , 1 , vidl[1] ); 128781Speter putprintf( ",%d" , 0 , w ); 129781Speter putprintf( " .text" , 0 ); 1302165Speter stabgvar( vidl[1] , p2type( np ) , o2 , w , line ); 131*3836Speter vp -> extra_flags |= NGLOBAL; 132*3836Speter } else { 133*3836Speter vp -> extra_flags |= NLOCAL; 134781Speter } 135781Speter # endif PC 136781Speter } 137781Speter # ifdef PTREE 138781Speter { 139781Speter pPointer *Vars; 140781Speter pPointer Var = VarDecl( ovidl , vtype ); 141781Speter 142781Speter pSeize( PorFHeader[ nesting ] ); 143781Speter Vars = &( pDEF( PorFHeader[ nesting ] ).PorFVars ); 144781Speter *Vars = ListAppend( *Vars , Var ); 145781Speter pRelease( PorFHeader[ nesting ] ); 146781Speter } 147781Speter # endif 148781Speter } 149781Speter #endif 150781Speter 151781Speter varend() 152781Speter { 153781Speter 154781Speter foredecl(); 155781Speter #ifndef PI0 1563229Smckusic sizes[cbn].om_max = sizes[cbn].curtmps.om_off; 157781Speter #else 158781Speter send(REVVEND); 159781Speter #endif 160781Speter } 161781Speter 162781Speter /* 163781Speter * Evening 164781Speter */ 1653082Smckusic long 1663082Smckusic leven(w) 1673082Smckusic register long w; 1683082Smckusic { 1693082Smckusic if (w < 0) 1703082Smckusic return (w & 0xfffffffe); 1713082Smckusic return ((w+1) & 0xfffffffe); 1723082Smckusic } 1733082Smckusic 1743082Smckusic int 175781Speter even(w) 176781Speter register int w; 177781Speter { 1783082Smckusic return leven((long)w); 179781Speter } 180781Speter 181781Speter /* 182781Speter * Find the width of a type in bytes. 183781Speter */ 184781Speter width(np) 185781Speter struct nl *np; 186781Speter { 187781Speter 188781Speter return (lwidth(np)); 189781Speter } 190781Speter 191781Speter long 192781Speter lwidth(np) 193781Speter struct nl *np; 194781Speter { 195781Speter register struct nl *p; 196781Speter long w; 197781Speter 198781Speter p = np; 199781Speter if (p == NIL) 200781Speter return (0); 201781Speter loop: 202781Speter switch (p->class) { 203781Speter case TYPE: 204781Speter switch (nloff(p)) { 205781Speter case TNIL: 206781Speter return (2); 207781Speter case TSTR: 208781Speter case TSET: 209781Speter panic("width"); 210781Speter default: 211781Speter p = p->type; 212781Speter goto loop; 213781Speter } 214781Speter case ARRAY: 215781Speter return (aryconst(p, 0)); 216781Speter case PTR: 217781Speter return ( sizeof ( int * ) ); 218781Speter case FILET: 2192075Smckusic return ( sizeof(struct iorec) + lwidth( p -> type ) ); 220781Speter case RANGE: 221781Speter if (p->type == nl+TDOUBLE) 222781Speter #ifdef DEBUG 223781Speter return (hp21mx ? 4 : 8); 224781Speter #else 225781Speter return (8); 226781Speter #endif 227781Speter case SCAL: 228781Speter return (bytes(p->range[0], p->range[1])); 229781Speter case SET: 230781Speter setran(p->type); 2313082Smckusic return roundup((int)((set.uprbp >> 3) + 1), 2323082Smckusic (long)(A_SET)); 233781Speter case STR: 234781Speter case RECORD: 235781Speter return ( p->value[NL_OFFS] ); 236781Speter default: 237781Speter panic("wclass"); 238781Speter } 239781Speter } 240781Speter 241781Speter /* 242781Speter * round up x to a multiple of y 243781Speter * for computing offsets of aligned things. 244781Speter * y had better be positive. 245781Speter * rounding is in the direction of x. 246781Speter */ 247781Speter long 248781Speter roundup( x , y ) 2493082Smckusic int x; 250781Speter register long y; 251781Speter { 252781Speter 253781Speter if ( y == 0 ) { 254781Speter return 0; 255781Speter } 256781Speter if ( x >= 0 ) { 257781Speter return ( ( ( x + ( y - 1 ) ) / y ) * y ); 258781Speter } else { 259781Speter return ( ( ( x - ( y - 1 ) ) / y ) * y ); 260781Speter } 261781Speter } 262781Speter 263781Speter /* 264781Speter * alignment of an object using the c alignment scheme 265781Speter */ 266781Speter int 267781Speter align( np ) 268781Speter struct nl *np; 269781Speter { 270781Speter register struct nl *p; 271781Speter 272781Speter p = np; 273781Speter if ( p == NIL ) { 274781Speter return 0; 275781Speter } 276781Speter alignit: 277781Speter switch ( p -> class ) { 278781Speter case TYPE: 279781Speter switch ( nloff( p ) ) { 280781Speter case TNIL: 281781Speter return A_POINT; 282781Speter case TSTR: 283781Speter return A_CHAR; 284781Speter case TSET: 285781Speter return A_SET; 286781Speter default: 287781Speter p = p -> type; 288781Speter goto alignit; 289781Speter } 290781Speter case ARRAY: 291781Speter /* 292781Speter * arrays are aligned as their component types 293781Speter */ 294781Speter p = p -> type; 295781Speter goto alignit; 296781Speter case PTR: 297781Speter return A_POINT; 298781Speter case FILET: 299781Speter return A_FILET; 300781Speter case RANGE: 301781Speter if ( p -> type == nl+TDOUBLE ) { 302781Speter return A_DOUBLE; 303781Speter } 304781Speter /* else, fall through */ 305781Speter case SCAL: 306781Speter switch ( bytes( p -> range[0] , p -> range[1] ) ) { 307781Speter case 4: 308781Speter return A_LONG; 309781Speter case 2: 310781Speter return A_SHORT; 311781Speter case 1: 312781Speter return A_CHAR; 313781Speter default: 314781Speter panic( "align: scal" ); 315781Speter } 316781Speter case SET: 317781Speter return A_SET; 318781Speter case STR: 319781Speter return A_CHAR; 320781Speter case RECORD: 321781Speter /* 322781Speter * follow chain through all fields in record, 323781Speter * taking max of alignments of types of fields. 324781Speter * short circuit out if i reach the maximum alignment. 325781Speter * this is pretty likely, as A_MAX is only 4. 326781Speter */ 327781Speter { 328781Speter register long recalign; 329781Speter register long fieldalign; 330781Speter 331781Speter recalign = A_MIN; 332781Speter p = p -> chain; 333781Speter while ( ( p != NIL ) && ( recalign < A_MAX ) ) { 334781Speter fieldalign = align( p -> type ); 335781Speter if ( fieldalign > recalign ) { 336781Speter recalign = fieldalign; 337781Speter } 338781Speter p = p -> chain; 339781Speter } 340781Speter return recalign; 341781Speter } 342781Speter default: 343781Speter panic( "align" ); 344781Speter } 345781Speter } 346781Speter 347781Speter /* 348781Speter * Return the width of an element 349781Speter * of a n time subscripted np. 350781Speter */ 351781Speter long aryconst(np, n) 352781Speter struct nl *np; 353781Speter int n; 354781Speter { 355781Speter register struct nl *p; 356781Speter long s, d; 357781Speter 358781Speter if ((p = np) == NIL) 359781Speter return (NIL); 360781Speter if (p->class != ARRAY) 361781Speter panic("ary"); 362781Speter s = lwidth(p->type); 363781Speter /* 364781Speter * Arrays of anything but characters are word aligned. 365781Speter */ 366781Speter if (s & 1) 367781Speter if (s != 1) 368781Speter s++; 369781Speter /* 370781Speter * Skip the first n subscripts 371781Speter */ 372781Speter while (n >= 0) { 373781Speter p = p->chain; 374781Speter n--; 375781Speter } 376781Speter /* 377781Speter * Sum across remaining subscripts. 378781Speter */ 379781Speter while (p != NIL) { 380781Speter if (p->class != RANGE && p->class != SCAL) 381781Speter panic("aryran"); 382781Speter d = p->range[1] - p->range[0] + 1; 383781Speter s *= d; 384781Speter p = p->chain; 385781Speter } 386781Speter return (s); 387781Speter } 388781Speter 389781Speter /* 390781Speter * Find the lower bound of a set, and also its size in bits. 391781Speter */ 392781Speter setran(q) 393781Speter struct nl *q; 394781Speter { 395781Speter register lb, ub; 396781Speter register struct nl *p; 397781Speter 398781Speter p = q; 399781Speter if (p == NIL) 400781Speter return (NIL); 401781Speter lb = p->range[0]; 402781Speter ub = p->range[1]; 403781Speter if (p->class != RANGE && p->class != SCAL) 404781Speter panic("setran"); 405781Speter set.lwrb = lb; 406781Speter /* set.(upperbound prime) = number of bits - 1; */ 407781Speter set.uprbp = ub-lb; 408781Speter } 409781Speter 410781Speter /* 411781Speter * Return the number of bytes required to hold an arithmetic quantity 412781Speter */ 413781Speter bytes(lb, ub) 414781Speter long lb, ub; 415781Speter { 416781Speter 417781Speter #ifndef DEBUG 418781Speter if (lb < -32768 || ub > 32767) 419781Speter return (4); 420781Speter else if (lb < -128 || ub > 127) 421781Speter return (2); 422781Speter #else 423781Speter if (!hp21mx && (lb < -32768 || ub > 32767)) 424781Speter return (4); 425781Speter if (lb < -128 || ub > 127) 426781Speter return (2); 427781Speter #endif 428781Speter else 429781Speter return (1); 430781Speter } 431