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