1781Speter /* Copyright (c) 1979 Regents of the University of California */ 2781Speter 3*8681Speter static char sccsid[] = "@(#)var.c 1.13 10/19/82"; 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 */ 217951Speter varbeg( lineofyvar , r ) 227951Speter int lineofyvar; 23781Speter { 247951Speter static bool var_order = FALSE; 257951Speter static bool var_seen = FALSE; 26781Speter 27837Speter /* this allows for multiple declaration 28781Speter * parts except when the "standard" 29781Speter * option has been specified. 30781Speter * If routine segment is being compiled, 31781Speter * do level one processing. 32781Speter */ 33781Speter 34781Speter #ifndef PI1 35837Speter if (!progseen) 36837Speter level1(); 377951Speter line = lineofyvar; 38837Speter if ( parts[ cbn ] & RPRT ) { 39837Speter if ( opt( 's' ) ) { 40781Speter standard(); 417951Speter error("Variable declarations should precede routine declarations"); 42837Speter } else { 437951Speter if ( !var_order ) { 447951Speter var_order = TRUE; 457951Speter warning(); 467951Speter error("Variable declarations should precede routine declarations"); 477951Speter } 48837Speter } 49781Speter } 50837Speter if ( parts[ cbn ] & VPRT ) { 51837Speter if ( opt( 's' ) ) { 52837Speter standard(); 537951Speter error("All variables should be declared in one var part"); 54837Speter } else { 557951Speter if ( !var_seen ) { 567951Speter var_seen = TRUE; 577951Speter warning(); 587951Speter error("All variables should be declared in one var part"); 597951Speter } 60837Speter } 61837Speter } 62837Speter parts[ cbn ] |= VPRT; 63781Speter #endif 64781Speter /* 65781Speter * #ifndef PI0 663229Smckusic * sizes[cbn].om_max = sizes[cbn].curtmps.om_off = -DPOFF1; 67781Speter * #endif 68781Speter */ 69781Speter forechain = NIL; 70781Speter #ifdef PI0 71781Speter send(REVVBEG); 72781Speter #endif 73781Speter } 74781Speter 75781Speter var(vline, vidl, vtype) 76781Speter #ifdef PI0 77781Speter int vline, *vidl, *vtype; 78781Speter { 79781Speter register struct nl *np; 80781Speter register int *vl; 81781Speter 82781Speter np = gtype(vtype); 83781Speter line = vline; 84781Speter for (vl = vidl; vl != NIL; vl = vl[2]) { 85781Speter } 86781Speter } 87781Speter send(REVVAR, vline, vidl, vtype); 88781Speter } 89781Speter #else 90781Speter int vline; 91781Speter register int *vidl; 92781Speter int *vtype; 93781Speter { 94781Speter register struct nl *np; 95781Speter register struct om *op; 96781Speter long w; 97781Speter int o2; 98781Speter int *ovidl = vidl; 993836Speter struct nl *vp; 100781Speter 101781Speter np = gtype(vtype); 102781Speter line = vline; 1033949Speter w = lwidth(np); 104781Speter op = &sizes[cbn]; 105781Speter for (; vidl != NIL; vidl = vidl[2]) { 106781Speter # ifdef OBJ 1073235Smckusic op->curtmps.om_off = 1083235Smckusic roundup((int)(op->curtmps.om_off-w), (long)align(np)); 1093235Smckusic o2 = op -> curtmps.om_off; 110781Speter # endif OBJ 111781Speter # ifdef PC 112781Speter if ( cbn == 1 ) { 113781Speter /* 114781Speter * global variables are not accessed off the fp 115781Speter * but rather by their names. 116781Speter */ 117781Speter o2 = 0; 118781Speter } else { 119781Speter /* 120781Speter * locals are aligned, too. 121781Speter */ 1223229Smckusic op->curtmps.om_off = 1233229Smckusic roundup((int)(op->curtmps.om_off - w), 1243082Smckusic (long)align(np)); 1253229Smckusic o2 = op -> curtmps.om_off; 126781Speter } 127781Speter # endif PC 1283836Speter vp = enter(defnl(vidl[1], VAR, np, o2)); 129781Speter if ( np -> nl_flags & NFILES ) { 130781Speter dfiles[ cbn ] = TRUE; 131781Speter } 132781Speter # ifdef PC 133781Speter if ( cbn == 1 ) { 134781Speter putprintf( " .data" , 0 ); 1353949Speter putprintf( " .align %d" , 0 , dotalign(align(np))); 136781Speter putprintf( " .comm " , 1 ); 137781Speter putprintf( EXTFORMAT , 1 , vidl[1] ); 138781Speter putprintf( ",%d" , 0 , w ); 139781Speter putprintf( " .text" , 0 ); 1402165Speter stabgvar( vidl[1] , p2type( np ) , o2 , w , line ); 1413836Speter vp -> extra_flags |= NGLOBAL; 1423836Speter } else { 1433836Speter vp -> extra_flags |= NLOCAL; 144781Speter } 145781Speter # endif PC 146781Speter } 147781Speter # ifdef PTREE 148781Speter { 149781Speter pPointer *Vars; 150781Speter pPointer Var = VarDecl( ovidl , vtype ); 151781Speter 152781Speter pSeize( PorFHeader[ nesting ] ); 153781Speter Vars = &( pDEF( PorFHeader[ nesting ] ).PorFVars ); 154781Speter *Vars = ListAppend( *Vars , Var ); 155781Speter pRelease( PorFHeader[ nesting ] ); 156781Speter } 157781Speter # endif 158781Speter } 159781Speter #endif 160781Speter 161781Speter varend() 162781Speter { 163781Speter 164781Speter foredecl(); 165781Speter #ifndef PI0 1663229Smckusic sizes[cbn].om_max = sizes[cbn].curtmps.om_off; 167781Speter #else 168781Speter send(REVVEND); 169781Speter #endif 170781Speter } 171781Speter 172781Speter /* 173781Speter * Evening 174781Speter */ 1753082Smckusic long 1763082Smckusic leven(w) 1773082Smckusic register long w; 1783082Smckusic { 1793082Smckusic if (w < 0) 1803082Smckusic return (w & 0xfffffffe); 1813082Smckusic return ((w+1) & 0xfffffffe); 1823082Smckusic } 1833082Smckusic 1843082Smckusic int 185781Speter even(w) 186781Speter register int w; 187781Speter { 1883082Smckusic return leven((long)w); 189781Speter } 190781Speter 191781Speter /* 192781Speter * Find the width of a type in bytes. 193781Speter */ 194781Speter width(np) 195781Speter struct nl *np; 196781Speter { 197781Speter 198781Speter return (lwidth(np)); 199781Speter } 200781Speter 201781Speter long 202781Speter lwidth(np) 203781Speter struct nl *np; 204781Speter { 205781Speter register struct nl *p; 206781Speter long w; 207781Speter 208781Speter p = np; 209781Speter if (p == NIL) 210781Speter return (0); 211781Speter loop: 212781Speter switch (p->class) { 213781Speter case TYPE: 214781Speter switch (nloff(p)) { 215781Speter case TNIL: 216781Speter return (2); 217781Speter case TSTR: 218781Speter case TSET: 219781Speter panic("width"); 220781Speter default: 221781Speter p = p->type; 222781Speter goto loop; 223781Speter } 224781Speter case ARRAY: 225781Speter return (aryconst(p, 0)); 226781Speter case PTR: 227781Speter return ( sizeof ( int * ) ); 228781Speter case FILET: 2292075Smckusic return ( sizeof(struct iorec) + lwidth( p -> type ) ); 230781Speter case RANGE: 231781Speter if (p->type == nl+TDOUBLE) 232781Speter #ifdef DEBUG 233781Speter return (hp21mx ? 4 : 8); 234781Speter #else 235781Speter return (8); 236781Speter #endif 237781Speter case SCAL: 238781Speter return (bytes(p->range[0], p->range[1])); 239781Speter case SET: 240781Speter setran(p->type); 2413082Smckusic return roundup((int)((set.uprbp >> 3) + 1), 2423082Smckusic (long)(A_SET)); 243781Speter case STR: 244781Speter case RECORD: 245781Speter return ( p->value[NL_OFFS] ); 246781Speter default: 247781Speter panic("wclass"); 248781Speter } 249781Speter } 250781Speter 251781Speter /* 252781Speter * round up x to a multiple of y 253781Speter * for computing offsets of aligned things. 254781Speter * y had better be positive. 255781Speter * rounding is in the direction of x. 256781Speter */ 257781Speter long 258781Speter roundup( x , y ) 2593082Smckusic int x; 260781Speter register long y; 261781Speter { 262781Speter 263781Speter if ( y == 0 ) { 2644030Smckusic return x; 265781Speter } 266781Speter if ( x >= 0 ) { 267781Speter return ( ( ( x + ( y - 1 ) ) / y ) * y ); 268781Speter } else { 269781Speter return ( ( ( x - ( y - 1 ) ) / y ) * y ); 270781Speter } 271781Speter } 272781Speter 273781Speter /* 274781Speter * alignment of an object using the c alignment scheme 275781Speter */ 276781Speter int 277781Speter align( np ) 278781Speter struct nl *np; 279781Speter { 280781Speter register struct nl *p; 281781Speter 282781Speter p = np; 283781Speter if ( p == NIL ) { 284781Speter return 0; 285781Speter } 286781Speter alignit: 287781Speter switch ( p -> class ) { 288781Speter case TYPE: 289781Speter switch ( nloff( p ) ) { 290781Speter case TNIL: 291781Speter return A_POINT; 292781Speter case TSTR: 293781Speter return A_CHAR; 294781Speter case TSET: 295781Speter return A_SET; 296781Speter default: 297781Speter p = p -> type; 298781Speter goto alignit; 299781Speter } 300781Speter case ARRAY: 301781Speter /* 302781Speter * arrays are aligned as their component types 303781Speter */ 304781Speter p = p -> type; 305781Speter goto alignit; 306781Speter case PTR: 307781Speter return A_POINT; 308781Speter case FILET: 309781Speter return A_FILET; 310781Speter case RANGE: 311781Speter if ( p -> type == nl+TDOUBLE ) { 312781Speter return A_DOUBLE; 313781Speter } 314781Speter /* else, fall through */ 315781Speter case SCAL: 316781Speter switch ( bytes( p -> range[0] , p -> range[1] ) ) { 317781Speter case 4: 318781Speter return A_LONG; 319781Speter case 2: 320781Speter return A_SHORT; 321781Speter case 1: 322781Speter return A_CHAR; 323781Speter default: 324781Speter panic( "align: scal" ); 325781Speter } 326781Speter case SET: 327781Speter return A_SET; 328781Speter case STR: 329781Speter return A_CHAR; 330781Speter case RECORD: 331781Speter /* 332*8681Speter * the alignment of a record is in its align_info field 333*8681Speter * why don't we use this for the rest of the namelist? 334781Speter */ 335*8681Speter return p -> align_info; 336781Speter default: 337781Speter panic( "align" ); 338781Speter } 339781Speter } 340781Speter 3413949Speter /* 3423949Speter * given an alignment, return power of two for .align pseudo-op 3433949Speter */ 3443949Speter dotalign( alignment ) 3453949Speter int alignment; 3463949Speter { 3473949Speter 3483949Speter switch ( alignment ) { 3493949Speter case A_CHAR: /* 3503949Speter * also 3513949Speter * A_STRUCT 3523949Speter */ 3533949Speter return 0; 3543949Speter case A_SHORT: 3553949Speter return 1; 3563949Speter case A_LONG: /* 3573949Speter * also 3583949Speter * A_POINT, A_INT, A_FLOAT, A_DOUBLE, 3593949Speter * A_STACK, A_FILET, A_SET 3603949Speter */ 3613949Speter return 2; 3623949Speter } 3633949Speter } 3643949Speter 365781Speter /* 366781Speter * Return the width of an element 367781Speter * of a n time subscripted np. 368781Speter */ 369781Speter long aryconst(np, n) 370781Speter struct nl *np; 371781Speter int n; 372781Speter { 373781Speter register struct nl *p; 374781Speter long s, d; 375781Speter 376781Speter if ((p = np) == NIL) 377781Speter return (NIL); 378781Speter if (p->class != ARRAY) 379781Speter panic("ary"); 380781Speter s = lwidth(p->type); 381781Speter /* 382781Speter * Arrays of anything but characters are word aligned. 383781Speter */ 384781Speter if (s & 1) 385781Speter if (s != 1) 386781Speter s++; 387781Speter /* 388781Speter * Skip the first n subscripts 389781Speter */ 390781Speter while (n >= 0) { 391781Speter p = p->chain; 392781Speter n--; 393781Speter } 394781Speter /* 395781Speter * Sum across remaining subscripts. 396781Speter */ 397781Speter while (p != NIL) { 398781Speter if (p->class != RANGE && p->class != SCAL) 399781Speter panic("aryran"); 400781Speter d = p->range[1] - p->range[0] + 1; 401781Speter s *= d; 402781Speter p = p->chain; 403781Speter } 404781Speter return (s); 405781Speter } 406781Speter 407781Speter /* 408781Speter * Find the lower bound of a set, and also its size in bits. 409781Speter */ 410781Speter setran(q) 411781Speter struct nl *q; 412781Speter { 413781Speter register lb, ub; 414781Speter register struct nl *p; 415781Speter 416781Speter p = q; 417781Speter if (p == NIL) 418781Speter return (NIL); 419781Speter lb = p->range[0]; 420781Speter ub = p->range[1]; 421781Speter if (p->class != RANGE && p->class != SCAL) 422781Speter panic("setran"); 423781Speter set.lwrb = lb; 424781Speter /* set.(upperbound prime) = number of bits - 1; */ 425781Speter set.uprbp = ub-lb; 426781Speter } 427781Speter 428781Speter /* 429781Speter * Return the number of bytes required to hold an arithmetic quantity 430781Speter */ 431781Speter bytes(lb, ub) 432781Speter long lb, ub; 433781Speter { 434781Speter 435781Speter #ifndef DEBUG 436781Speter if (lb < -32768 || ub > 32767) 437781Speter return (4); 438781Speter else if (lb < -128 || ub > 127) 439781Speter return (2); 440781Speter #else 441781Speter if (!hp21mx && (lb < -32768 || ub > 32767)) 442781Speter return (4); 443781Speter if (lb < -128 || ub > 127) 444781Speter return (2); 445781Speter #endif 446781Speter else 447781Speter return (1); 448781Speter } 449