|
|
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.