|
|
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[] = "@(#)proc.c 5.2 (Berkeley) 6/9/85";
9: #endif not lint
10:
11: /*
12: * proc.c
13: *
14: * Routines for handling procedures, f77 compiler, pass 1.
15: *
16: * University of Utah CS Dept modification history:
17: *
18: * $Header: proc.c,v 1.5 86/02/12 15:28:58 rcs Exp $
19: * $Log: proc.c,v $
20: * Revision 1.5 86/02/12 15:28:58 rcs
21: * 4.3 F77. C. Keating.
22: *
23: * Revision 3.11 85/06/04 03:45:29 donn
24: * Changed retval() to recognize that a function declaration might have
25: * bombed out earlier, leaving an error node behind...
26: *
27: * Revision 3.10 85/03/08 23:13:06 donn
28: * Finally figured out why function calls and array elements are not legal
29: * dummy array dimension declarator elements. Hacked safedim() to stop 'em.
30: *
31: * Revision 3.9 85/02/02 00:26:10 donn
32: * Removed the call to entrystab() in enddcl() -- this was redundant (it was
33: * also done in startproc()) and confusing to dbx to boot.
34: *
35: * Revision 3.8 85/01/14 04:21:53 donn
36: * Added changes to implement Jerry's '-q' option.
37: *
38: * Revision 3.7 85/01/11 21:10:35 donn
39: * In conjunction with other changes to implement SAVE statements, function
40: * nameblocks were changed to make it appear that they are 'saved' too --
41: * this arranges things so that function return values are forced out of
42: * register before a return.
43: *
44: * Revision 3.6 84/12/10 19:27:20 donn
45: * comblock() signals an illegal common block name by returning a null pointer,
46: * but incomm() wasn't able to handle it, leading to core dumps. I put the
47: * fix in incomm() to pick up null common blocks.
48: *
49: * Revision 3.5 84/11/21 20:33:31 donn
50: * It seems that I/O elements are treated as character strings so that their
51: * length can be passed to the I/O routines... Unfortunately the compiler
52: * assumes that no temporaries can be of type CHARACTER and casually tosses
53: * length and type info away when removing TEMP blocks. This has been fixed...
54: *
55: * Revision 3.4 84/11/05 22:19:30 donn
56: * Fixed a silly bug in the last fix.
57: *
58: * Revision 3.3 84/10/29 08:15:23 donn
59: * Added code to check the type and shape of subscript declarations,
60: * per Jerry Berkman's suggestion.
61: *
62: * Revision 3.2 84/10/29 05:52:07 donn
63: * Added change suggested by Jerry Berkman to report an error when an array
64: * is redimensioned.
65: *
66: * Revision 3.1 84/10/13 02:12:31 donn
67: * Merged Jerry Berkman's version into mine.
68: *
69: * Revision 2.1 84/07/19 12:04:09 donn
70: * Changed comment headers for UofU.
71: *
72: * Revision 1.6 84/07/19 11:32:15 donn
73: * Incorporated fix to setbound() to detect backward array subscript limits.
74: * The fix is by Bob Corbett, donated by Jerry Berkman.
75: *
76: * Revision 1.5 84/07/18 18:25:50 donn
77: * Fixed problem with doentry() where a placeholder for a return value
78: * was not allocated if the first entry didn't require one but a later
79: * entry did.
80: *
81: * Revision 1.4 84/05/24 20:52:09 donn
82: * Installed firewall #ifdef around the code that recycles stack temporaries,
83: * since it seems to be broken and lacks a good fix for the time being.
84: *
85: * Revision 1.3 84/04/16 09:50:46 donn
86: * Fixed mkargtemp() so that it only passes back a copy of a temporary, keeping
87: * the original for its own use. This fixes a set of bugs that are caused by
88: * elements in the argtemplist getting stomped on.
89: *
90: * Revision 1.2 84/02/28 21:12:58 donn
91: * Added Berkeley changes for subroutine call argument temporaries fix.
92: *
93: */
94:
95: #include "defs.h"
96:
97: #ifdef SDB
98: # include <a.out.h>
99: # ifndef N_SO
100: # include <stab.h>
101: # endif
102: #endif
103:
104: extern flag namesflag;
105:
106: typedef
107: struct SizeList
108: {
109: struct SizeList *next;
110: ftnint size;
111: struct VarList *vars;
112: }
113: sizelist;
114:
115:
116: typedef
117: struct VarList
118: {
119: struct VarList *next;
120: Namep np;
121: struct Equivblock *ep;
122: }
123: varlist;
124:
125:
126: LOCAL sizelist *varsizes;
127:
128:
129: /* start a new procedure */
130:
131: newproc()
132: {
133: if(parstate != OUTSIDE)
134: {
135: execerr("missing end statement", CNULL);
136: endproc();
137: }
138:
139: parstate = INSIDE;
140: procclass = CLMAIN; /* default */
141: }
142:
143:
144:
145: /* end of procedure. generate variables, epilogs, and prologs */
146:
147: endproc()
148: {
149: struct Labelblock *lp;
150:
151: if(parstate < INDATA)
152: enddcl();
153: if(ctlstack >= ctls)
154: err("DO loop or BLOCK IF not closed");
155: for(lp = labeltab ; lp < labtabend ; ++lp)
156: if(lp->stateno!=0 && lp->labdefined==NO)
157: errstr("missing statement number %s", convic(lp->stateno) );
158:
159: if (optimflag)
160: optimize();
161:
162: outiodata();
163: epicode();
164: procode();
165: donmlist();
166: dobss();
167:
168: #if FAMILY == PCC
169: putbracket();
170: #endif
171: procinit(); /* clean up for next procedure */
172: }
173:
174:
175:
176: /* End of declaration section of procedure. Allocate storage. */
177:
178: enddcl()
179: {
180: register struct Entrypoint *ep;
181:
182: parstate = INEXEC;
183: docommon();
184: doequiv();
185: docomleng();
186: for(ep = entries ; ep ; ep = ep->entnextp) {
187: doentry(ep);
188: }
189: }
190:
191: /* ROUTINES CALLED WHEN ENCOUNTERING ENTRY POINTS */
192:
193: /* Main program or Block data */
194:
195: startproc(prgname, class)
196: Namep prgname;
197: int class;
198: {
199: struct Extsym *progname;
200: register struct Entrypoint *p;
201:
202: if(prgname)
203: procname = prgname->varname;
204: if(namesflag == YES) {
205: fprintf(diagfile, " %s", (class==CLMAIN ? "MAIN" : "BLOCK DATA") );
206: if(prgname)
207: fprintf(diagfile, " %s", varstr(XL, procname) );
208: fprintf(diagfile, ":\n");
209: }
210:
211: if( prgname )
212: progname = newentry( prgname );
213: else
214: progname = NULL;
215:
216: p = ALLOC(Entrypoint);
217: if(class == CLMAIN)
218: puthead("MAIN_", CLMAIN);
219: else
220: puthead(CNULL, CLBLOCK);
221: if(class == CLMAIN)
222: newentry( mkname(5, "MAIN") );
223: p->entryname = progname;
224: p->entrylabel = newlabel();
225: entries = p;
226:
227: procclass = class;
228: retlabel = newlabel();
229: #ifdef SDB
230: if(sdbflag) {
231: entrystab(p,class);
232: }
233: #endif
234: }
235:
236: /* subroutine or function statement */
237:
238: struct Extsym *newentry(v)
239: register Namep v;
240: {
241: register struct Extsym *p;
242:
243: p = mkext( varunder(VL, v->varname) );
244:
245: if(p==NULL || p->extinit || ! ONEOF(p->extstg, M(STGUNKNOWN)|M(STGEXT)) )
246: {
247: if(p == 0)
248: dclerr("invalid entry name", v);
249: else dclerr("external name already used", v);
250: return(0);
251: }
252: v->vstg = STGAUTO;
253: v->vprocclass = PTHISPROC;
254: v->vclass = CLPROC;
255: p->extstg = STGEXT;
256: p->extinit = YES;
257: return(p);
258: }
259:
260:
261: entrypt(class, type, length, entname, args)
262: int class, type;
263: ftnint length;
264: Namep entname;
265: chainp args;
266: {
267: struct Extsym *entry;
268: register Namep q;
269: register struct Entrypoint *p, *ep;
270:
271: if(namesflag == YES) {
272: if(class == CLENTRY)
273: fprintf(diagfile, " entry ");
274: if(entname)
275: fprintf(diagfile, " %s", varstr(XL, entname->varname) );
276: fprintf(diagfile, ":\n");
277: }
278:
279: if( entname->vclass == CLPARAM ) {
280: errstr("entry name %s used in 'parameter' statement",
281: varstr(XL, entname->varname) );
282: return;
283: }
284: if( ((type == TYSUBR) || (class == CLENTRY && proctype == TYSUBR))
285: && (entname->vtype != TYUNKNOWN && entname->vtype != TYSUBR) ) {
286: errstr("subroutine entry %s previously declared",
287: varstr(XL, entname->varname) );
288: return;
289: }
290: if( (entname->vstg != STGEXT && entname->vstg != STGUNKNOWN)
291: || (entname->vdim != NULL) ) {
292: errstr("subroutine or function entry %s previously declared",
293: varstr(XL, entname->varname) );
294: return;
295: }
296:
297: if( (class == CLPROC || class == CLENTRY) && type != TYSUBR )
298: /* arrange to save function return values */
299: entname->vsave = YES;
300:
301: entry = newentry( entname );
302:
303: if(class != CLENTRY)
304: puthead( varstr(XL, procname = entry->extname), class);
305: q = mkname(VL, nounder(XL,entry->extname) );
306:
307: if( (type = lengtype(type, (int) length)) != TYCHAR)
308: length = 0;
309: if(class == CLPROC)
310: {
311: procclass = CLPROC;
312: proctype = type;
313: procleng = length;
314:
315: retlabel = newlabel();
316: if(type == TYSUBR)
317: ret0label = newlabel();
318: }
319:
320: p = ALLOC(Entrypoint);
321: if(entries) /* put new block at end of entries list */
322: {
323: for(ep = entries; ep->entnextp; ep = ep->entnextp)
324: ;
325: ep->entnextp = p;
326: }
327: else
328: entries = p;
329:
330: p->entryname = entry;
331: p->arglist = args;
332: p->entrylabel = newlabel();
333: p->enamep = q;
334:
335: if(class == CLENTRY)
336: {
337: class = CLPROC;
338: if(proctype == TYSUBR)
339: type = TYSUBR;
340: }
341:
342: q->vclass = class;
343: q->vprocclass = PTHISPROC;
344: settype(q, type, (int) length);
345: /* hold all initial entry points till end of declarations */
346: if(parstate >= INDATA) {
347: doentry(p);
348: }
349: #ifdef SDB
350: if(sdbflag)
351: { /* may need to preserve CLENTRY here */
352: entrystab(p,class);
353: }
354: #endif
355: }
356:
357: /* generate epilogs */
358:
359: LOCAL epicode()
360: {
361: register int i;
362:
363: if(procclass==CLPROC)
364: {
365: if(proctype==TYSUBR)
366: {
367: putlabel(ret0label);
368: if(substars)
369: putforce(TYINT, ICON(0) );
370: putlabel(retlabel);
371: goret(TYSUBR);
372: }
373: else {
374: putlabel(retlabel);
375: if(multitype)
376: {
377: typeaddr = autovar(1, TYADDR, PNULL);
378: putbranch( cpexpr(typeaddr) );
379: for(i = 0; i < NTYPES ; ++i)
380: if(rtvlabel[i] != 0)
381: {
382: putlabel(rtvlabel[i]);
383: retval(i);
384: }
385: }
386: else
387: retval(proctype);
388: }
389: }
390:
391: else if(procclass != CLBLOCK)
392: {
393: putlabel(retlabel);
394: goret(TYSUBR);
395: }
396: }
397:
398:
399: /* generate code to return value of type t */
400:
401: LOCAL retval(t)
402: register int t;
403: {
404: register Addrp p;
405:
406: switch(t)
407: {
408: case TYCHAR:
409: case TYCOMPLEX:
410: case TYDCOMPLEX:
411: break;
412:
413: case TYLOGICAL:
414: t = tylogical;
415: case TYADDR:
416: case TYSHORT:
417: case TYLONG:
418: p = (Addrp) cpexpr(retslot);
419: p->vtype = t;
420: putforce(t, p);
421: break;
422:
423: case TYREAL:
424: case TYDREAL:
425: p = (Addrp) cpexpr(retslot);
426: p->vtype = t;
427: putforce(t, p);
428: break;
429:
430: case TYERROR:
431: return; /* someone else already complained */
432:
433: default:
434: badtype("retval", t);
435: }
436: goret(t);
437: }
438:
439:
440: /* Allocate extra argument array if needed. Generate prologs. */
441:
442: LOCAL procode()
443: {
444: register struct Entrypoint *p;
445: Addrp argvec;
446:
447: #if TARGET==GCOS
448: argvec = autovar(lastargslot/SZADDR, TYADDR, PNULL);
449: #else
450: if(lastargslot>0 && nentry>1)
451: #if TARGET == VAX || TARGET == TAHOE
452: argvec = autovar(1 + lastargslot/SZADDR, TYADDR, PNULL);
453: #else
454: argvec = autovar(lastargslot/SZADDR, TYADDR, PNULL);
455: #endif
456: else
457: argvec = NULL;
458: #endif
459:
460:
461: #if TARGET == PDP11
462: /* for the optimizer */
463: if(fudgelabel)
464: putlabel(fudgelabel);
465: #endif
466:
467: for(p = entries ; p ; p = p->entnextp)
468: prolog(p, argvec);
469:
470: #if FAMILY == PCC
471: putrbrack(procno);
472: #endif
473:
474: prendproc();
475: }
476:
477:
478: /*
479: manipulate argument lists (allocate argument slot positions)
480: * keep track of return types and labels
481: */
482:
483: LOCAL doentry(ep)
484: struct Entrypoint *ep;
485: {
486: register int type;
487: register Namep np;
488: chainp p;
489: register Namep q;
490: Addrp mkarg();
491:
492: ++nentry;
493: if(procclass == CLMAIN)
494: {
495: if (optimflag)
496: optbuff (SKLABEL, 0, ep->entrylabel, 0);
497: else
498: putlabel(ep->entrylabel);
499: return;
500: }
501: else if(procclass == CLBLOCK)
502: return;
503:
504: impldcl( np = mkname(VL, nounder(XL, ep->entryname->extname) ) );
505: type = np->vtype;
506: if(proctype == TYUNKNOWN)
507: if( (proctype = type) == TYCHAR)
508: procleng = (np->vleng ? np->vleng->constblock.const.ci : (ftnint) (-1));
509:
510: if(proctype == TYCHAR)
511: {
512: if(type != TYCHAR)
513: err("noncharacter entry of character function");
514: else if( (np->vleng ? np->vleng->constblock.const.ci : (ftnint) (-1)) != procleng)
515: err("mismatched character entry lengths");
516: }
517: else if(type == TYCHAR)
518: err("character entry of noncharacter function");
519: else if(type != proctype)
520: multitype = YES;
521: if(rtvlabel[type] == 0)
522: rtvlabel[type] = newlabel();
523: ep->typelabel = rtvlabel[type];
524:
525: if(type == TYCHAR)
526: {
527: if(chslot < 0)
528: {
529: chslot = nextarg(TYADDR);
530: chlgslot = nextarg(TYLENG);
531: }
532: np->vstg = STGARG;
533: np->vardesc.varno = chslot;
534: if(procleng < 0)
535: np->vleng = (expptr) mkarg(TYLENG, chlgslot);
536: }
537: else if( ISCOMPLEX(type) )
538: {
539: np->vstg = STGARG;
540: if(cxslot < 0)
541: cxslot = nextarg(TYADDR);
542: np->vardesc.varno = cxslot;
543: }
544: else if(type != TYSUBR)
545: {
546: if(retslot == NULL)
547: retslot = autovar(1, TYDREAL, PNULL);
548: np->vstg = STGAUTO;
549: np->voffset = retslot->memoffset->constblock.const.ci;
550: }
551:
552: for(p = ep->arglist ; p ; p = p->nextp)
553: if(! (( q = (Namep) (p->datap) )->vdcldone) )
554: q->vardesc.varno = nextarg(TYADDR);
555:
556: for(p = ep->arglist ; p ; p = p->nextp)
557: if(! (( q = (Namep) (p->datap) )->vdcldone) )
558: {
559: impldcl(q);
560: q->vdcldone = YES;
561: if(q->vtype == TYCHAR)
562: {
563: if(q->vleng == NULL) /* character*(*) */
564: q->vleng = (expptr)
565: mkarg(TYLENG, nextarg(TYLENG) );
566: else if(nentry == 1)
567: nextarg(TYLENG);
568: }
569: else if(q->vclass==CLPROC && nentry==1)
570: nextarg(TYLENG) ;
571: #ifdef SDB
572: if(sdbflag) {
573: namestab(q);
574: }
575: #endif
576: }
577:
578: if (optimflag)
579: optbuff (SKLABEL, 0, ep->entrylabel, 0);
580: else
581: putlabel(ep->entrylabel);
582: }
583:
584:
585:
586: LOCAL nextarg(type)
587: int type;
588: {
589: int k;
590: k = lastargslot;
591: lastargslot += typesize[type];
592: return(k);
593: }
594:
595: /* generate variable references */
596:
597: LOCAL dobss()
598: {
599: register struct Hashentry *p;
600: register Namep q;
601: register int i;
602: int align;
603: ftnint leng, iarrl;
604: char *memname();
605: int qstg, qclass, qtype;
606:
607: pruse(asmfile, USEBSS);
608: varsizes = NULL;
609:
610: for(p = hashtab ; p<lasthash ; ++p)
611: if(q = p->varp)
612: {
613: qstg = q->vstg;
614: qtype = q->vtype;
615: qclass = q->vclass;
616:
617: if( (qclass==CLUNKNOWN && qstg!=STGARG) ||
618: (qclass==CLVAR && qstg==STGUNKNOWN) )
619: warn1("local variable %s never used", varstr(VL,q->varname) );
620: else if(qclass==CLPROC && q->vprocclass==PEXTERNAL && qstg!=STGARG)
621: mkext(varunder(VL, q->varname)) ->extstg = STGEXT;
622:
623: if (qclass == CLVAR && qstg == STGBSS)
624: {
625: if (SMALLVAR(q->varsize))
626: {
627: enlist(q->varsize, q, NULL);
628: q->inlcomm = NO;
629: }
630: else
631: {
632: if (q->init == NO)
633: {
634: preven(ALIDOUBLE);
635: prlocvar(memname(qstg, q->vardesc.varno), q->varsize);
636: q->inlcomm = YES;
637: }
638: else
639: prlocdata(memname(qstg, q->vardesc.varno), q->varsize,
640: q->vtype, q->initoffset, &(q->inlcomm));
641: }
642: }
643: else if(qclass==CLVAR && qstg!=STGARG)
644: {
645: if(q->vdim && !ISICON(q->vdim->nelt) )
646: dclerr("adjustable dimension on non-argument", q);
647: if(qtype==TYCHAR && (q->vleng==NULL || !ISICON(q->vleng)))
648: dclerr("adjustable leng on nonargument", q);
649: }
650:
651: chkdim(q);
652: }
653:
654: for (i = 0 ; i < nequiv ; ++i)
655: if ( (leng = eqvclass[i].eqvleng) != 0 )
656: {
657: if (SMALLVAR(leng))
658: enlist(leng, NULL, eqvclass + i);
659: else if (eqvclass[i].init == NO)
660: {
661: preven(ALIDOUBLE);
662: prlocvar(memname(STGEQUIV, i), leng);
663: eqvclass[i].inlcomm = YES;
664: }
665: else
666: prlocdata(memname(STGEQUIV, i), leng, TYDREAL,
667: eqvclass[i].initoffset, &(eqvclass[i].inlcomm));
668: }
669:
670: outlocvars();
671: #ifdef SDB
672: if(sdbflag) {
673: for(p = hashtab ; p<lasthash ; ++p) if(q = p->varp) {
674: qstg = q->vstg;
675: qclass = q->vclass;
676: if( ONEOF(qclass, M(CLVAR))) {
677: if (! ONEOF(qstg,M(STGCOMMON)|M(STGARG) ) ) namestab(q);
678: }
679: }
680: }
681: #endif
682:
683: close(vdatafile);
684: close(vchkfile);
685: unlink(vdatafname);
686: unlink(vchkfname);
687: vdatahwm = 0;
688: }
689:
690:
691:
692: donmlist()
693: {
694: register struct Hashentry *p;
695: register Namep q;
696:
697: pruse(asmfile, USEINIT);
698:
699: for(p=hashtab; p<lasthash; ++p)
700: if( (q = p->varp) && q->vclass==CLNAMELIST)
701: namelist(q);
702: }
703:
704:
705: doext()
706: {
707: struct Extsym *p;
708:
709: for(p = extsymtab ; p<nextext ; ++p)
710: prext(p);
711: }
712:
713:
714:
715:
716: ftnint iarrlen(q)
717: register Namep q;
718: {
719: ftnint leng;
720:
721: leng = typesize[q->vtype];
722: if(leng <= 0)
723: return(-1);
724: if(q->vdim)
725: if( ISICON(q->vdim->nelt) )
726: leng *= q->vdim->nelt->constblock.const.ci;
727: else return(-1);
728: if(q->vleng)
729: if( ISICON(q->vleng) )
730: leng *= q->vleng->constblock.const.ci;
731: else return(-1);
732: return(leng);
733: }
734:
735: /* This routine creates a static block representing the namelist.
736: An equivalent declaration of the structure produced is:
737: struct namelist
738: {
739: char namelistname[16];
740: struct namelistentry
741: {
742: char varname[16];
743: char *varaddr;
744: int type; # negative means -type= number of chars
745: struct dimensions *dimp; # null means scalar
746: } names[];
747: };
748:
749: struct dimensions
750: {
751: int numberofdimensions;
752: int numberofelements
753: int baseoffset;
754: int span[numberofdimensions];
755: };
756: where the namelistentry list terminates with a null varname
757: If dimp is not null, then the corner element of the array is at
758: varaddr. However, the element with subscripts (i1,...,in) is at
759: varaddr - dimp->baseoffset + sizeoftype * (i1+span[0]*(i2+span[1]*...)
760: */
761:
762: namelist(np)
763: Namep np;
764: {
765: register chainp q;
766: register Namep v;
767: register struct Dimblock *dp;
768: char *memname();
769: int type, dimno, dimoffset;
770: flag bad;
771:
772:
773: preven(ALILONG);
774: fprintf(asmfile, LABELFMT, memname(STGINIT, np->vardesc.varno));
775: putstr(asmfile, varstr(VL, np->varname), 16);
776: dimno = ++lastvarno;
777: dimoffset = 0;
778: bad = NO;
779:
780: for(q = np->varxptr.namelist ; q ; q = q->nextp)
781: {
782: vardcl( v = (Namep) (q->datap) );
783: type = v->vtype;
784: if( ONEOF(v->vstg, MSKSTATIC) )
785: {
786: preven(ALILONG);
787: putstr(asmfile, varstr(VL,v->varname), 16);
788: praddr(asmfile, v->vstg, v->vardesc.varno, v->voffset);
789: prconi(asmfile, TYINT,
790: type==TYCHAR ?
791: -(v->vleng->constblock.const.ci) : (ftnint) type);
792: if(v->vdim)
793: {
794: praddr(asmfile, STGINIT, dimno, (ftnint)dimoffset);
795: dimoffset += 3 + v->vdim->ndim;
796: }
797: else
798: praddr(asmfile, STGNULL,0,(ftnint) 0);
799: }
800: else
801: {
802: dclerr("may not appear in namelist", v);
803: bad = YES;
804: }
805: }
806:
807: if(bad)
808: return;
809:
810: putstr(asmfile, "", 16);
811:
812: if(dimoffset > 0)
813: {
814: fprintf(asmfile, LABELFMT, memname(STGINIT,dimno));
815: for(q = np->varxptr.namelist ; q ; q = q->nextp)
816: if(dp = q->datap->nameblock.vdim)
817: {
818: int i;
819: prconi(asmfile, TYINT, (ftnint) (dp->ndim) );
820: prconi(asmfile, TYINT,
821: (ftnint) (dp->nelt->constblock.const.ci) );
822: prconi(asmfile, TYINT,
823: (ftnint) (dp->baseoffset->constblock.const.ci));
824: for(i=0; i<dp->ndim ; ++i)
825: prconi(asmfile, TYINT,
826: dp->dims[i].dimsize->constblock.const.ci);
827: }
828: }
829:
830: }
831:
832: LOCAL docommon()
833: {
834: register struct Extsym *p;
835: register chainp q;
836: struct Dimblock *t;
837: expptr neltp;
838: register Namep v;
839: ftnint size;
840: int type;
841:
842: for(p = extsymtab ; p<nextext ; ++p)
843: if(p->extstg==STGCOMMON)
844: {
845: #ifdef SDB
846: if(sdbflag)
847: prstab(varstr(XL,p->extname), N_BCOMM, 0, 0);
848: #endif
849: for(q = p->extp ; q ; q = q->nextp)
850: {
851: v = (Namep) (q->datap);
852: if(v->vdcldone == NO)
853: vardcl(v);
854: type = v->vtype;
855: if(p->extleng % typealign[type] != 0)
856: {
857: dclerr("common alignment", v);
858: p->extleng = roundup(p->extleng, typealign[type]);
859: }
860: v->voffset = p->extleng;
861: v->vardesc.varno = p - extsymtab;
862: if(type == TYCHAR)
863: size = v->vleng->constblock.const.ci;
864: else size = typesize[type];
865: if(t = v->vdim)
866: if( (neltp = t->nelt) && ISCONST(neltp) )
867: size *= neltp->constblock.const.ci;
868: else
869: dclerr("adjustable array in common", v);
870: p->extleng += size;
871: #ifdef SDB
872: if(sdbflag)
873: {
874: namestab(v);
875: }
876: #endif
877: }
878:
879: frchain( &(p->extp) );
880: #ifdef SDB
881: if(sdbflag)
882: prstab(varstr(XL,p->extname), N_ECOMM, 0, 0);
883: #endif
884: }
885: }
886:
887:
888:
889:
890:
891: LOCAL docomleng()
892: {
893: register struct Extsym *p;
894:
895: for(p = extsymtab ; p < nextext ; ++p)
896: if(p->extstg == STGCOMMON)
897: {
898: if(p->maxleng!=0 && p->extleng!=0 && p->maxleng!=p->extleng
899: && !eqn(XL,"_BLNK__ ",p->extname) )
900: warn1("incompatible lengths for common block %s",
901: nounder(XL, p->extname) );
902: if(p->maxleng < p->extleng)
903: p->maxleng = p->extleng;
904: p->extleng = 0;
905: }
906: }
907:
908:
909:
910:
911: /* ROUTINES DEALING WITH AUTOMATIC AND TEMPORARY STORAGE */
912:
913: /* frees a temporary block */
914:
915: frtemp(p)
916: Tempp p;
917: {
918: Addrp t;
919:
920: if (optimflag)
921: {
922: if (p->tag != TTEMP)
923: badtag ("frtemp",p->tag);
924: t = p->memalloc;
925: }
926: else
927: t = (Addrp) p;
928:
929: /* restore clobbered character string lengths */
930: if(t->vtype==TYCHAR && t->varleng!=0)
931: {
932: frexpr(t->vleng);
933: t->vleng = ICON(t->varleng);
934: }
935:
936: /* put block on chain of temps to be reclaimed */
937: holdtemps = mkchain(t, holdtemps);
938: }
939:
940:
941:
942: /* allocate an automatic variable slot */
943:
944: Addrp autovar(nelt, t, lengp)
945: register int nelt, t;
946: expptr lengp;
947: {
948: ftnint leng;
949: register Addrp q;
950:
951: if(lengp)
952: if( ISICON(lengp) )
953: leng = lengp->constblock.const.ci;
954: else {
955: fatal("automatic variable of nonconstant length");
956: }
957: else
958: leng = typesize[t];
959: autoleng = roundup( autoleng, typealign[t]);
960:
961: q = ALLOC(Addrblock);
962: q->tag = TADDR;
963: q->vtype = t;
964: if(lengp)
965: {
966: q->vleng = ICON(leng);
967: q->varleng = leng;
968: }
969: q->vstg = STGAUTO;
970: q->memno = newlabel();
971: q->ntempelt = nelt;
972: #if TARGET==PDP11 || TARGET==VAX || TARGET == TAHOE
973: /* stack grows downward */
974: autoleng += nelt*leng;
975: q->memoffset = ICON( - autoleng );
976: #else
977: q->memoffset = ICON( autoleng );
978: autoleng += nelt*leng;
979: #endif
980:
981: return(q);
982: }
983:
984:
985:
986: /*
987: * create a temporary block (TTEMP) when optimizing,
988: * an ordinary TADDR block when not optimizing
989: */
990:
991: Tempp mktmpn(nelt, type, lengp)
992: int nelt;
993: register int type;
994: expptr lengp;
995: {
996: ftnint leng;
997: chainp p, oldp;
998: register Tempp q;
999: Addrp altemp;
1000:
1001: if (! optimflag)
1002: return ( (Tempp) mkaltmpn(nelt,type,lengp) );
1003: if(type==TYUNKNOWN || type==TYERROR)
1004: badtype("mktmpn", type);
1005:
1006: if(type==TYCHAR)
1007: if( ISICON(lengp) )
1008: leng = lengp->constblock.const.ci;
1009: else {
1010: err("adjustable length");
1011: return( (Tempp) errnode() );
1012: }
1013: else
1014: leng = typesize[type];
1015:
1016: q = ALLOC(Tempblock);
1017: q->tag = TTEMP;
1018: q->vtype = type;
1019: if(type == TYCHAR)
1020: {
1021: q->vleng = ICON(leng);
1022: q->varleng = leng;
1023: }
1024:
1025: altemp = ALLOC(Addrblock);
1026: altemp->tag = TADDR;
1027: altemp->vstg = STGUNKNOWN;
1028: q->memalloc = altemp;
1029:
1030: q->ntempelt = nelt;
1031: q->istemp = YES;
1032: return(q);
1033: }
1034:
1035:
1036:
1037: Addrp mktemp(type, lengp)
1038: int type;
1039: expptr lengp;
1040: {
1041: return( (Addrp) mktmpn(1,type,lengp) );
1042: }
1043:
1044:
1045:
1046: /* allocate a temporary location for the given temporary block;
1047: if already allocated, return its location */
1048:
1049: Addrp altmpn(tp)
1050: Tempp tp;
1051:
1052: {
1053: Addrp t, q;
1054:
1055: if (tp->tag != TTEMP)
1056: badtag ("altmpn",tp->tag);
1057:
1058: t = tp->memalloc;
1059: if (t->vstg != STGUNKNOWN)
1060: {
1061: if (tp->vtype == TYCHAR)
1062: {
1063: /*
1064: * Unformatted I/O parameters are treated like character
1065: * strings (sigh) -- propagate type and length.
1066: */
1067: t = (Addrp) cpexpr(t);
1068: t->vtype = tp->vtype;
1069: t->vleng = tp->vleng;
1070: t->varleng = tp->varleng;
1071: }
1072: return (t);
1073: }
1074:
1075: q = mkaltmpn (tp->ntempelt, tp->vtype, tp->vleng);
1076: cpn (sizeof(struct Addrblock), (char*)q, (char*)t);
1077: free ( (charptr) q);
1078: return(t);
1079: }
1080:
1081:
1082:
1083: /* create and allocate space immediately for a temporary */
1084:
1085: Addrp mkaltemp(type,lengp)
1086: int type;
1087: expptr lengp;
1088: {
1089: return (mkaltmpn(1,type,lengp));
1090: }
1091:
1092:
1093:
1094: Addrp mkaltmpn(nelt,type,lengp)
1095: int nelt;
1096: register int type;
1097: expptr lengp;
1098: {
1099: ftnint leng;
1100: chainp p, oldp;
1101: register Addrp q;
1102:
1103: if(type==TYUNKNOWN || type==TYERROR)
1104: badtype("mkaltmpn", type);
1105:
1106: if(type==TYCHAR)
1107: if( ISICON(lengp) )
1108: leng = lengp->constblock.const.ci;
1109: else {
1110: err("adjustable length");
1111: return( (Addrp) errnode() );
1112: }
1113:
1114: /*
1115: * if a temporary of appropriate shape is on the templist,
1116: * remove it from the list and return it
1117: */
1118:
1119: #ifdef notdef
1120: /*
1121: * This code is broken until SKFRTEMP slots can be processed in putopt()
1122: * instead of in optimize() -- all kinds of things in putpcc.c can
1123: * bomb because of this. Sigh.
1124: */
1125: for(oldp=CHNULL, p=templist ; p ; oldp=p, p=p->nextp)
1126: {
1127: q = (Addrp) (p->datap);
1128: if(q->vtype==type && q->ntempelt==nelt &&
1129: (type!=TYCHAR || q->vleng->constblock.const.ci==leng) )
1130: {
1131: if(oldp)
1132: oldp->nextp = p->nextp;
1133: else
1134: templist = p->nextp;
1135: free( (charptr) p);
1136:
1137: if (debugflag[14])
1138: fprintf(diagfile,"mkaltmpn reusing offset %d\n",
1139: q->memoffset->constblock.const.ci);
1140: return(q);
1141: }
1142: }
1143: #endif notdef
1144: q = autovar(nelt, type, lengp);
1145: q->istemp = YES;
1146:
1147: if (debugflag[14])
1148: fprintf(diagfile,"mkaltmpn new offset %d\n",
1149: q->memoffset->constblock.const.ci);
1150: return(q);
1151: }
1152:
1153:
1154:
1155: /* The following routine is a patch which is only needed because the */
1156: /* code for processing actual arguments for calls does not allocate */
1157: /* the temps it needs before optimization takes place. A better */
1158: /* solution is possible, but I do not have the time to implement it */
1159: /* now. */
1160: /* */
1161: /* Robert P. Corbett */
1162:
1163: Addrp
1164: mkargtemp(type, lengp)
1165: int type;
1166: expptr lengp;
1167: {
1168: ftnint leng;
1169: chainp oldp, p;
1170: Addrp q;
1171:
1172: if (type == TYUNKNOWN || type == TYERROR)
1173: badtype("mkargtemp", type);
1174:
1175: if (type == TYCHAR)
1176: {
1177: if (ISICON(lengp))
1178: leng = lengp->constblock.const.ci;
1179: else
1180: {
1181: err("adjustable length");
1182: return ((Addrp) errnode());
1183: }
1184: }
1185:
1186: oldp = CHNULL;
1187: p = argtemplist;
1188:
1189: while (p)
1190: {
1191: q = (Addrp) (p->datap);
1192: if (q->vtype == type
1193: && (type != TYCHAR || q->vleng->constblock.const.ci == leng))
1194: {
1195: if (oldp)
1196: oldp->nextp = p->nextp;
1197: else
1198: argtemplist = p->nextp;
1199:
1200: p->nextp = activearglist;
1201: activearglist = p;
1202:
1203: return ((Addrp) cpexpr(q));
1204: }
1205:
1206: oldp = p;
1207: p = p->nextp;
1208: }
1209:
1210: q = autovar(1, type, lengp);
1211: activearglist = mkchain(q, activearglist);
1212: return ((Addrp) cpexpr(q));
1213: }
1214:
1215: /* VARIOUS ROUTINES FOR PROCESSING DECLARATIONS */
1216:
1217: struct Extsym *comblock(len, s)
1218: register int len;
1219: register char *s;
1220: {
1221: struct Extsym *p;
1222:
1223: if(len == 0)
1224: {
1225: s = BLANKCOMMON;
1226: len = strlen(s);
1227: }
1228: p = mkext( varunder(len, s) );
1229: if(p->extstg == STGUNKNOWN)
1230: p->extstg = STGCOMMON;
1231: else if(p->extstg != STGCOMMON)
1232: {
1233: errstr("%s cannot be a common block name", s);
1234: return(0);
1235: }
1236:
1237: return( p );
1238: }
1239:
1240:
1241: incomm(c, v)
1242: struct Extsym *c;
1243: Namep v;
1244: {
1245: if(v->vstg != STGUNKNOWN)
1246: dclerr("incompatible common declaration", v);
1247: else
1248: {
1249: if(c == (struct Extsym *) 0)
1250: return; /* Illegal common block name upstream */
1251: v->vstg = STGCOMMON;
1252: c->extp = hookup(c->extp, mkchain(v,CHNULL) );
1253: }
1254: }
1255:
1256:
1257:
1258:
1259: settype(v, type, length)
1260: register Namep v;
1261: register int type;
1262: register int length;
1263: {
1264: if(type == TYUNKNOWN)
1265: return;
1266:
1267: if(type==TYSUBR && v->vtype!=TYUNKNOWN && v->vstg==STGARG)
1268: {
1269: v->vtype = TYSUBR;
1270: frexpr(v->vleng);
1271: }
1272: else if(type < 0) /* storage class set */
1273: {
1274: if(v->vstg == STGUNKNOWN)
1275: v->vstg = - type;
1276: else if(v->vstg != -type)
1277: dclerr("incompatible storage declarations", v);
1278: }
1279: else if(v->vtype == TYUNKNOWN)
1280: {
1281: if( (v->vtype = lengtype(type, length))==TYCHAR && length>=0)
1282: v->vleng = ICON(length);
1283: }
1284: else if(v->vtype!=type || (type==TYCHAR && v->vleng->constblock.const.ci!=length) )
1285: dclerr("incompatible type declarations", v);
1286: }
1287:
1288:
1289:
1290:
1291:
1292: lengtype(type, length)
1293: register int type;
1294: register int length;
1295: {
1296: switch(type)
1297: {
1298: case TYREAL:
1299: if(length == 8)
1300: return(TYDREAL);
1301: if(length == 4)
1302: goto ret;
1303: break;
1304:
1305: case TYCOMPLEX:
1306: if(length == 16)
1307: return(TYDCOMPLEX);
1308: if(length == 8)
1309: goto ret;
1310: break;
1311:
1312: case TYSHORT:
1313: case TYDREAL:
1314: case TYDCOMPLEX:
1315: case TYCHAR:
1316: case TYUNKNOWN:
1317: case TYSUBR:
1318: case TYERROR:
1319: goto ret;
1320:
1321: case TYLOGICAL:
1322: if(length == typesize[TYLOGICAL])
1323: goto ret;
1324: break;
1325:
1326: case TYLONG:
1327: if(length == 0 )
1328: return(tyint);
1329: if(length == 2)
1330: return(TYSHORT);
1331: if(length == 4 )
1332: goto ret;
1333: break;
1334: default:
1335: badtype("lengtype", type);
1336: }
1337:
1338: if(length != 0)
1339: err("incompatible type-length combination");
1340:
1341: ret:
1342: return(type);
1343: }
1344:
1345:
1346:
1347:
1348:
1349: setintr(v)
1350: register Namep v;
1351: {
1352: register int k;
1353:
1354: if(v->vstg == STGUNKNOWN)
1355: v->vstg = STGINTR;
1356: else if(v->vstg!=STGINTR)
1357: dclerr("incompatible use of intrinsic function", v);
1358: if(v->vclass==CLUNKNOWN)
1359: v->vclass = CLPROC;
1360: if(v->vprocclass == PUNKNOWN)
1361: v->vprocclass = PINTRINSIC;
1362: else if(v->vprocclass != PINTRINSIC)
1363: dclerr("invalid intrinsic declaration", v);
1364: if(k = intrfunct(v->varname))
1365: v->vardesc.varno = k;
1366: else
1367: dclerr("unknown intrinsic function", v);
1368: }
1369:
1370:
1371:
1372: setext(v)
1373: register Namep v;
1374: {
1375: if(v->vclass == CLUNKNOWN)
1376: v->vclass = CLPROC;
1377: else if(v->vclass != CLPROC)
1378: dclerr("conflicting declarations", v);
1379:
1380: if(v->vprocclass == PUNKNOWN)
1381: v->vprocclass = PEXTERNAL;
1382: else if(v->vprocclass != PEXTERNAL)
1383: dclerr("conflicting declarations", v);
1384: }
1385:
1386:
1387:
1388:
1389: /* create dimensions block for array variable */
1390:
1391: setbound(v, nd, dims)
1392: register Namep v;
1393: int nd;
1394: struct { expptr lb, ub; } dims[ ];
1395: {
1396: register expptr q, t;
1397: register struct Dimblock *p;
1398: int i;
1399:
1400: if(v->vclass == CLUNKNOWN)
1401: v->vclass = CLVAR;
1402: else if(v->vclass != CLVAR)
1403: {
1404: dclerr("only variables may be arrays", v);
1405: return;
1406: }
1407: if(v->vdim)
1408: {
1409: dclerr("redimensioned array", v);
1410: return;
1411: }
1412:
1413: v->vdim = p = (struct Dimblock *)
1414: ckalloc( sizeof(int) + (3+6*nd)*sizeof(expptr) );
1415: p->ndim = nd;
1416: p->nelt = ICON(1);
1417:
1418: for(i=0 ; i<nd ; ++i)
1419: {
1420: #ifdef SDB
1421: if(sdbflag) {
1422: /* Save the bounds trees built up by the grammar routines for use in stabs */
1423:
1424: if(dims[i].lb == NULL) p->dims[i].lb=ICON(1);
1425: else p->dims[i].lb= (expptr) cpexpr(dims[i].lb);
1426: if(ISCONST(p->dims[i].lb)) p->dims[i].lbaddr = (expptr) PNULL;
1427: else p->dims[i].lbaddr = (expptr) autovar(1, tyint, PNULL);
1428:
1429: if(dims[i].ub == NULL) p->dims[i].ub=ICON(1);
1430: else p->dims[i].ub = (expptr) cpexpr(dims[i].ub);
1431: if(ISCONST(p->dims[i].ub)) p->dims[i].ubaddr = (expptr) PNULL;
1432: else p->dims[i].ubaddr = (expptr) autovar(1, tyint, PNULL);
1433: }
1434: #endif
1435: if( (q = dims[i].ub) == NULL)
1436: {
1437: if(i == nd-1)
1438: {
1439: frexpr(p->nelt);
1440: p->nelt = NULL;
1441: }
1442: else
1443: err("only last bound may be asterisk");
1444: p->dims[i].dimsize = ICON(1);;
1445: p->dims[i].dimexpr = NULL;
1446: }
1447: else
1448: {
1449: if(dims[i].lb)
1450: {
1451: q = mkexpr(OPMINUS, q, cpexpr(dims[i].lb));
1452: q = mkexpr(OPPLUS, q, ICON(1) );
1453: }
1454: if( ISCONST(q) )
1455: {
1456: if (!ISINT(q->headblock.vtype)) {
1457: dclerr("dimension bounds must be integer expression", v);
1458: frexpr(q);
1459: q = ICON(0);
1460: }
1461: if ( q->constblock.const.ci <= 0)
1462: {
1463: dclerr("array bounds out of sequence", v);
1464: frexpr(q);
1465: q = ICON(0);
1466: }
1467: p->dims[i].dimsize = q;
1468: p->dims[i].dimexpr = (expptr) PNULL;
1469: }
1470: else {
1471: p->dims[i].dimsize = (expptr) autovar(1, tyint, PNULL);
1472: p->dims[i].dimexpr = q;
1473: }
1474: if(p->nelt)
1475: p->nelt = mkexpr(OPSTAR, p->nelt,
1476: cpexpr(p->dims[i].dimsize) );
1477: }
1478: }
1479:
1480: q = dims[nd-1].lb;
1481: if(q == NULL)
1482: q = ICON(1);
1483:
1484: for(i = nd-2 ; i>=0 ; --i)
1485: {
1486: t = dims[i].lb;
1487: if(t == NULL)
1488: t = ICON(1);
1489: if(p->dims[i].dimsize)
1490: q = mkexpr(OPPLUS, t, mkexpr(OPSTAR, cpexpr(p->dims[i].dimsize), q) );
1491: }
1492:
1493: if( ISCONST(q) )
1494: {
1495: p->baseoffset = q;
1496: p->basexpr = NULL;
1497: }
1498: else
1499: {
1500: p->baseoffset = (expptr) autovar(1, tyint, PNULL);
1501: p->basexpr = q;
1502: }
1503: }
1504:
1505:
1506:
1507: /*
1508: * Check the dimensions of q to ensure that they are appropriately defined.
1509: */
1510: LOCAL chkdim(q)
1511: register Namep q;
1512: {
1513: register struct Dimblock *p;
1514: register int i;
1515: expptr e;
1516:
1517: if (q == NULL)
1518: return;
1519: if (q->vclass != CLVAR)
1520: return;
1521: if (q->vdim == NULL)
1522: return;
1523: p = q->vdim;
1524: for (i = 0; i < p->ndim; ++i)
1525: {
1526: #ifdef SDB
1527: if (sdbflag)
1528: {
1529: if (e = p->dims[i].lb)
1530: chkdime(e, q);
1531: if (e = p->dims[i].ub)
1532: chkdime(e, q);
1533: }
1534: else
1535: #endif SDB
1536: if (e = p->dims[i].dimexpr)
1537: chkdime(e, q);
1538: }
1539: }
1540:
1541:
1542:
1543: /*
1544: * The actual checking for chkdim() -- examines each expression.
1545: */
1546: LOCAL chkdime(expr, q)
1547: expptr expr;
1548: Namep q;
1549: {
1550: register expptr e;
1551:
1552: e = fixtype(cpexpr(expr));
1553: if (!ISINT(e->exprblock.vtype))
1554: dclerr("non-integer dimension", q);
1555: else if (!safedim(e))
1556: dclerr("undefined dimension", q);
1557: frexpr(e);
1558: return;
1559: }
1560:
1561:
1562:
1563: /*
1564: * A recursive routine to find undefined variables in dimension expressions.
1565: */
1566: LOCAL safedim(e)
1567: expptr e;
1568: {
1569: chainp cp;
1570:
1571: if (e == NULL)
1572: return 1;
1573: switch (e->tag)
1574: {
1575: case TEXPR:
1576: if (e->exprblock.opcode == OPCALL || e->exprblock.opcode == OPCCALL)
1577: return 0;
1578: return safedim(e->exprblock.leftp) && safedim(e->exprblock.rightp);
1579: case TADDR:
1580: switch (e->addrblock.vstg)
1581: {
1582: case STGCOMMON:
1583: case STGARG:
1584: case STGCONST:
1585: case STGEQUIV:
1586: if (e->addrblock.isarray)
1587: return 0;
1588: return safedim(e->addrblock.memoffset);
1589: default:
1590: return 0;
1591: }
1592: case TCONST:
1593: case TTEMP:
1594: return 1;
1595: }
1596: return 0;
1597: }
1598:
1599:
1600:
1601: LOCAL enlist(size, np, ep)
1602: ftnint size;
1603: Namep np;
1604: struct Equivblock *ep;
1605: {
1606: register sizelist *sp;
1607: register sizelist *t;
1608: register varlist *p;
1609:
1610: sp = varsizes;
1611:
1612: if (sp == NULL)
1613: {
1614: sp = ALLOC(SizeList);
1615: sp->size = size;
1616: varsizes = sp;
1617: }
1618: else
1619: {
1620: while (sp->size != size)
1621: {
1622: if (sp->next != NULL && sp->next->size <= size)
1623: sp = sp->next;
1624: else
1625: {
1626: t = sp;
1627: sp = ALLOC(SizeList);
1628: sp->size = size;
1629: sp->next = t->next;
1630: t->next = sp;
1631: }
1632: }
1633: }
1634:
1635: p = ALLOC(VarList);
1636: p->next = sp->vars;
1637: p->np = np;
1638: p->ep = ep;
1639:
1640: sp->vars = p;
1641:
1642: return;
1643: }
1644:
1645:
1646:
1647: outlocvars()
1648: {
1649:
1650: register varlist *first, *last;
1651: register varlist *vp, *t;
1652: register sizelist *sp, *sp1;
1653: register Namep np;
1654: register struct Equivblock *ep;
1655: register int i;
1656: register int alt;
1657: register int type;
1658: char sname[100];
1659: char setbuff[100];
1660:
1661: sp = varsizes;
1662: if (sp == NULL)
1663: return;
1664:
1665: vp = sp->vars;
1666: if (vp->np != NULL)
1667: {
1668: np = vp->np;
1669: sprintf(setbuff, "\t.set\tv.%d,v.%d\n", bsslabel,
1670: np->vardesc.varno);
1671: }
1672: else
1673: {
1674: i = vp->ep - eqvclass;
1675: sprintf(setbuff, "\t.set\tv.%d,q.%d\n", bsslabel, i + eqvstart);
1676: }
1677:
1678: first = last = NULL;
1679: alt = NO;
1680:
1681: while (sp != NULL)
1682: {
1683: vp = sp->vars;
1684: while (vp != NULL)
1685: {
1686: t = vp->next;
1687: if (alt == YES)
1688: {
1689: alt = NO;
1690: vp->next = first;
1691: first = vp;
1692: }
1693: else
1694: {
1695: alt = YES;
1696: if (last != NULL)
1697: last->next = vp;
1698: else
1699: first = vp;
1700: vp->next = NULL;
1701: last = vp;
1702: }
1703: vp = t;
1704: }
1705: sp1 = sp;
1706: sp = sp->next;
1707: free((char *) sp1);
1708: }
1709:
1710: vp = first;
1711: while(vp != NULL)
1712: {
1713: if (vp->np != NULL)
1714: {
1715: np = vp->np;
1716: sprintf(sname, "v.%d", np->vardesc.varno);
1717: pralign(typealign[np->vtype]);
1718: if (np->init)
1719: prlocdata(sname, np->varsize, np->vtype, np->initoffset,
1720: &(np->inlcomm));
1721: else
1722: {
1723: if (typealign[np->vtype] == 1)
1724: pralign(3);
1725: fprintf(initfile, "%s:\n\t.space\t%d\n", sname,
1726: np->varsize);
1727: }
1728: np->inlcomm = NO;
1729: }
1730: else
1731: {
1732: ep = vp->ep;
1733: i = ep - eqvclass;
1734: if (ep->eqvleng >= 8)
1735: type = TYDREAL;
1736: else if (ep->eqvleng >= 4)
1737: type = TYLONG;
1738: else if (ep->eqvleng >= 2)
1739: type = TYSHORT;
1740: else
1741: type = TYCHAR;
1742: sprintf(sname, "q.%d", i + eqvstart);
1743: if (ep->init)
1744: prlocdata(sname, ep->eqvleng, type, ep->initoffset,
1745: &(ep->inlcomm));
1746: else
1747: {
1748: pralign(typealign[type]);
1749: fprintf(initfile, "%s:\n\t.space\t%d\n", sname, ep->eqvleng);
1750: }
1751: ep->inlcomm = NO;
1752: }
1753: t = vp;
1754: vp = vp->next;
1755: free((char *) t);
1756: }
1757: fprintf(initfile, "%s\n", setbuff);
1758: return;
1759: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.