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