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: }

Defined functions

setran defined in line 456; used 7 times
var defined in line 84; used 2 times
varbeg defined in line 30; used 2 times
varend defined in line 177; used 2 times

Defined variables

sccsid defined in line 8; never used
vidl defined in line 102; used 10 times
vline defined in line 101; used 5 times
vtype defined in line 103; used 6 times
Last modified: 1985-07-27
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3477
Valid CSS Valid XHTML 1.0 Strict