|
|
1.1 root 1: /* Copyright (c) 1979 Regents of the University of California */
2:
3: static char sccsid[] = "@(#)var.c 1.3 9/2/80";
4:
5: #include "whoami.h"
6: #include "0.h"
7: #include "align.h"
8: #ifdef PC
9: # include "pc.h"
10: # include "pcops.h"
11: # include "iorec.h"
12: #endif PC
13:
14: /*
15: * Declare variables of a var part. DPOFF1 is
16: * the local variable storage for all prog/proc/func
17: * modules aside from the block mark. The total size
18: * of all the local variables is entered into the
19: * size array.
20: */
21: varbeg()
22: {
23:
24: /* this allows for multiple declaration
25: * parts except when the "standard"
26: * option has been specified.
27: * If routine segment is being compiled,
28: * do level one processing.
29: */
30:
31: #ifndef PI1
32: if (!progseen)
33: level1();
34: if ( parts[ cbn ] & RPRT ) {
35: if ( opt( 's' ) ) {
36: standard();
37: } else {
38: warning();
39: }
40: error("Variable declarations should precede routine declarations");
41: }
42: if ( parts[ cbn ] & VPRT ) {
43: if ( opt( 's' ) ) {
44: standard();
45: } else {
46: warning();
47: }
48: error("All variables should be declared in one var part");
49: }
50: parts[ cbn ] |= VPRT;
51: #endif
52: /*
53: * #ifndef PI0
54: * sizes[cbn].om_max = sizes[cbn].om_off = -DPOFF1;
55: * #endif
56: */
57: forechain = NIL;
58: #ifdef PI0
59: send(REVVBEG);
60: #endif
61: }
62:
63: var(vline, vidl, vtype)
64: #ifdef PI0
65: int vline, *vidl, *vtype;
66: {
67: register struct nl *np;
68: register int *vl;
69:
70: np = gtype(vtype);
71: line = vline;
72: for (vl = vidl; vl != NIL; vl = vl[2]) {
73: }
74: }
75: send(REVVAR, vline, vidl, vtype);
76: }
77: #else
78: int vline;
79: register int *vidl;
80: int *vtype;
81: {
82: register struct nl *np;
83: register struct om *op;
84: long w;
85: int o2;
86: int *ovidl = vidl;
87:
88: np = gtype(vtype);
89: line = vline;
90: /*
91: * widths are evened out
92: */
93: w = (lwidth(np) + 1) &~ 1;
94: op = &sizes[cbn];
95: for (; vidl != NIL; vidl = vidl[2]) {
96: # ifdef OBJ
97: op -> om_off = roundup( op -> om_off - w , align( np ) );
98: o2 = op -> om_off;
99: # endif OBJ
100: # ifdef PC
101: if ( cbn == 1 ) {
102: /*
103: * global variables are not accessed off the fp
104: * but rather by their names.
105: */
106: o2 = 0;
107: } else {
108: /*
109: * locals are aligned, too.
110: */
111: op -> om_off = roundup( op -> om_off - w
112: , align( np ) );
113: o2 = op -> om_off;
114: }
115: # endif PC
116: enter(defnl(vidl[1], VAR, np, o2));
117: if ( np -> nl_flags & NFILES ) {
118: dfiles[ cbn ] = TRUE;
119: }
120: # ifdef PC
121: if ( cbn == 1 ) {
122: putprintf( " .data" , 0 );
123: putprintf( " .comm " , 1 );
124: putprintf( EXTFORMAT , 1 , vidl[1] );
125: putprintf( ",%d" , 0 , w );
126: putprintf( " .text" , 0 );
127: }
128: stabvar( vidl[1] , p2type( np ) , cbn , o2 , w , line );
129: # endif PC
130: }
131: # ifdef PTREE
132: {
133: pPointer *Vars;
134: pPointer Var = VarDecl( ovidl , vtype );
135:
136: pSeize( PorFHeader[ nesting ] );
137: Vars = &( pDEF( PorFHeader[ nesting ] ).PorFVars );
138: *Vars = ListAppend( *Vars , Var );
139: pRelease( PorFHeader[ nesting ] );
140: }
141: # endif
142: }
143: #endif
144:
145: varend()
146: {
147:
148: foredecl();
149: #ifndef PI0
150: sizes[cbn].om_max = sizes[cbn].om_off;
151: #else
152: send(REVVEND);
153: #endif
154: }
155:
156: /*
157: * Evening
158: */
159: even(w)
160: register int w;
161: {
162: if (w < 0)
163: return (w & ~1);
164: return ((w+1) & ~1);
165: }
166:
167: /*
168: * Find the width of a type in bytes.
169: */
170: width(np)
171: struct nl *np;
172: {
173:
174: return (lwidth(np));
175: }
176:
177: long
178: lwidth(np)
179: struct nl *np;
180: {
181: register struct nl *p;
182: long w;
183:
184: p = np;
185: if (p == NIL)
186: return (0);
187: loop:
188: switch (p->class) {
189: case TYPE:
190: switch (nloff(p)) {
191: case TNIL:
192: return (2);
193: case TSTR:
194: case TSET:
195: panic("width");
196: default:
197: p = p->type;
198: goto loop;
199: }
200: case ARRAY:
201: return (aryconst(p, 0));
202: case PTR:
203: return ( sizeof ( int * ) );
204: case FILET:
205: # ifdef OBJ
206: return ( sizeof ( int * ) );
207: # endif OBJ
208: # ifdef PC
209: return ( sizeof(struct iorec)
210: + lwidth( p -> type ) );
211: # endif PC
212: case RANGE:
213: if (p->type == nl+TDOUBLE)
214: #ifdef DEBUG
215: return (hp21mx ? 4 : 8);
216: #else
217: return (8);
218: #endif
219: case SCAL:
220: return (bytes(p->range[0], p->range[1]));
221: case SET:
222: setran(p->type);
223: return roundup( ( set.uprbp >> 3 ) + 1 , A_SET );
224: case STR:
225: case RECORD:
226: return ( p->value[NL_OFFS] );
227: default:
228: panic("wclass");
229: }
230: }
231:
232: /*
233: * round up x to a multiple of y
234: * for computing offsets of aligned things.
235: * y had better be positive.
236: * rounding is in the direction of x.
237: */
238: long
239: roundup( x , y )
240: long x;
241: register long y;
242: {
243:
244: if ( y == 0 ) {
245: return 0;
246: }
247: if ( x >= 0 ) {
248: return ( ( ( x + ( y - 1 ) ) / y ) * y );
249: } else {
250: return ( ( ( x - ( y - 1 ) ) / y ) * y );
251: }
252: }
253:
254: /*
255: * alignment of an object using the c alignment scheme
256: */
257: int
258: align( np )
259: struct nl *np;
260: {
261: register struct nl *p;
262:
263: p = np;
264: if ( p == NIL ) {
265: return 0;
266: }
267: alignit:
268: switch ( p -> class ) {
269: case TYPE:
270: switch ( nloff( p ) ) {
271: case TNIL:
272: return A_POINT;
273: case TSTR:
274: return A_CHAR;
275: case TSET:
276: return A_SET;
277: default:
278: p = p -> type;
279: goto alignit;
280: }
281: case ARRAY:
282: /*
283: * arrays are aligned as their component types
284: */
285: p = p -> type;
286: goto alignit;
287: case PTR:
288: return A_POINT;
289: case FILET:
290: return A_FILET;
291: case RANGE:
292: if ( p -> type == nl+TDOUBLE ) {
293: return A_DOUBLE;
294: }
295: /* else, fall through */
296: case SCAL:
297: switch ( bytes( p -> range[0] , p -> range[1] ) ) {
298: case 4:
299: return A_LONG;
300: case 2:
301: return A_SHORT;
302: case 1:
303: return A_CHAR;
304: default:
305: panic( "align: scal" );
306: }
307: case SET:
308: return A_SET;
309: case STR:
310: return A_CHAR;
311: case RECORD:
312: /*
313: * follow chain through all fields in record,
314: * taking max of alignments of types of fields.
315: * short circuit out if i reach the maximum alignment.
316: * this is pretty likely, as A_MAX is only 4.
317: */
318: {
319: register long recalign;
320: register long fieldalign;
321:
322: recalign = A_MIN;
323: p = p -> chain;
324: while ( ( p != NIL ) && ( recalign < A_MAX ) ) {
325: fieldalign = align( p -> type );
326: if ( fieldalign > recalign ) {
327: recalign = fieldalign;
328: }
329: p = p -> chain;
330: }
331: return recalign;
332: }
333: default:
334: panic( "align" );
335: }
336: }
337:
338: /*
339: * Return the width of an element
340: * of a n time subscripted np.
341: */
342: long aryconst(np, n)
343: struct nl *np;
344: int n;
345: {
346: register struct nl *p;
347: long s, d;
348:
349: if ((p = np) == NIL)
350: return (NIL);
351: if (p->class != ARRAY)
352: panic("ary");
353: s = lwidth(p->type);
354: /*
355: * Arrays of anything but characters are word aligned.
356: */
357: if (s & 1)
358: if (s != 1)
359: s++;
360: /*
361: * Skip the first n subscripts
362: */
363: while (n >= 0) {
364: p = p->chain;
365: n--;
366: }
367: /*
368: * Sum across remaining subscripts.
369: */
370: while (p != NIL) {
371: if (p->class != RANGE && p->class != SCAL)
372: panic("aryran");
373: d = p->range[1] - p->range[0] + 1;
374: s *= d;
375: p = p->chain;
376: }
377: return (s);
378: }
379:
380: /*
381: * Find the lower bound of a set, and also its size in bits.
382: */
383: setran(q)
384: struct nl *q;
385: {
386: register lb, ub;
387: register struct nl *p;
388:
389: p = q;
390: if (p == NIL)
391: return (NIL);
392: lb = p->range[0];
393: ub = p->range[1];
394: if (p->class != RANGE && p->class != SCAL)
395: panic("setran");
396: set.lwrb = lb;
397: /* set.(upperbound prime) = number of bits - 1; */
398: set.uprbp = ub-lb;
399: }
400:
401: /*
402: * Return the number of bytes required to hold an arithmetic quantity
403: */
404: bytes(lb, ub)
405: long lb, ub;
406: {
407:
408: #ifndef DEBUG
409: if (lb < -32768 || ub > 32767)
410: return (4);
411: else if (lb < -128 || ub > 127)
412: return (2);
413: #else
414: if (!hp21mx && (lb < -32768 || ub > 32767))
415: return (4);
416: if (lb < -128 || ub > 127)
417: return (2);
418: #endif
419: else
420: return (1);
421: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.