xref: /csrg-svn/usr.bin/f77/pass1.vax/proc.c (revision 23477)
122861Smckusick /*
222861Smckusick  * Copyright (c) 1980 Regents of the University of California.
322861Smckusick  * All rights reserved.  The Berkeley software License Agreement
422861Smckusick  * specifies the terms and conditions for redistribution.
522861Smckusick  */
622861Smckusick 
722861Smckusick #ifndef lint
8*23477Smckusick static char sccsid[] = "@(#)proc.c	5.2 (Berkeley) 06/09/85";
922861Smckusick #endif not lint
1022861Smckusick 
1122861Smckusick /*
1222861Smckusick  * proc.c
1322861Smckusick  *
1422861Smckusick  * Routines for handling procedures, f77 compiler, pass 1.
1522861Smckusick  *
1622861Smckusick  * University of Utah CS Dept modification history:
1722861Smckusick  *
18*23477Smckusick  * $Header: proc.c,v 3.11 85/06/04 03:45:29 donn Exp $
1922861Smckusick  * $Log:	proc.c,v $
20*23477Smckusick  * Revision 3.11  85/06/04  03:45:29  donn
21*23477Smckusick  * Changed retval() to recognize that a function declaration might have
22*23477Smckusick  * bombed out earlier, leaving an error node behind...
23*23477Smckusick  *
2422861Smckusick  * Revision 3.10  85/03/08  23:13:06  donn
2522861Smckusick  * Finally figured out why function calls and array elements are not legal
2622861Smckusick  * dummy array dimension declarator elements.  Hacked safedim() to stop 'em.
2722861Smckusick  *
2822861Smckusick  * Revision 3.9  85/02/02  00:26:10  donn
2922861Smckusick  * Removed the call to entrystab() in enddcl() -- this was redundant (it was
3022861Smckusick  * also done in startproc()) and confusing to dbx to boot.
3122861Smckusick  *
3222861Smckusick  * Revision 3.8  85/01/14  04:21:53  donn
3322861Smckusick  * Added changes to implement Jerry's '-q' option.
3422861Smckusick  *
3522861Smckusick  * Revision 3.7  85/01/11  21:10:35  donn
3622861Smckusick  * In conjunction with other changes to implement SAVE statements, function
3722861Smckusick  * nameblocks were changed to make it appear that they are 'saved' too --
3822861Smckusick  * this arranges things so that function return values are forced out of
3922861Smckusick  * register before a return.
4022861Smckusick  *
4122861Smckusick  * Revision 3.6  84/12/10  19:27:20  donn
4222861Smckusick  * comblock() signals an illegal common block name by returning a null pointer,
4322861Smckusick  * but incomm() wasn't able to handle it, leading to core dumps.  I put the
4422861Smckusick  * fix in incomm() to pick up null common blocks.
4522861Smckusick  *
4622861Smckusick  * Revision 3.5  84/11/21  20:33:31  donn
4722861Smckusick  * It seems that I/O elements are treated as character strings so that their
4822861Smckusick  * length can be passed to the I/O routines...  Unfortunately the compiler
4922861Smckusick  * assumes that no temporaries can be of type CHARACTER and casually tosses
5022861Smckusick  * length and type info away when removing TEMP blocks.  This has been fixed...
5122861Smckusick  *
5222861Smckusick  * Revision 3.4  84/11/05  22:19:30  donn
5322861Smckusick  * Fixed a silly bug in the last fix.
5422861Smckusick  *
5522861Smckusick  * Revision 3.3  84/10/29  08:15:23  donn
5622861Smckusick  * Added code to check the type and shape of subscript declarations,
5722861Smckusick  * per Jerry Berkman's suggestion.
5822861Smckusick  *
5922861Smckusick  * Revision 3.2  84/10/29  05:52:07  donn
6022861Smckusick  * Added change suggested by Jerry Berkman to report an error when an array
6122861Smckusick  * is redimensioned.
6222861Smckusick  *
6322861Smckusick  * Revision 3.1  84/10/13  02:12:31  donn
6422861Smckusick  * Merged Jerry Berkman's version into mine.
6522861Smckusick  *
6622861Smckusick  * Revision 2.1  84/07/19  12:04:09  donn
6722861Smckusick  * Changed comment headers for UofU.
6822861Smckusick  *
6922861Smckusick  * Revision 1.6  84/07/19  11:32:15  donn
7022861Smckusick  * Incorporated fix to setbound() to detect backward array subscript limits.
7122861Smckusick  * The fix is by Bob Corbett, donated by Jerry Berkman.
7222861Smckusick  *
7322861Smckusick  * Revision 1.5  84/07/18  18:25:50  donn
7422861Smckusick  * Fixed problem with doentry() where a placeholder for a return value
7522861Smckusick  * was not allocated if the first entry didn't require one but a later
7622861Smckusick  * entry did.
7722861Smckusick  *
7822861Smckusick  * Revision 1.4  84/05/24  20:52:09  donn
7922861Smckusick  * Installed firewall #ifdef around the code that recycles stack temporaries,
8022861Smckusick  * since it seems to be broken and lacks a good fix for the time being.
8122861Smckusick  *
8222861Smckusick  * Revision 1.3  84/04/16  09:50:46  donn
8322861Smckusick  * Fixed mkargtemp() so that it only passes back a copy of a temporary, keeping
8422861Smckusick  * the original for its own use.  This fixes a set of bugs that are caused by
8522861Smckusick  * elements in the argtemplist getting stomped on.
8622861Smckusick  *
8722861Smckusick  * Revision 1.2  84/02/28  21:12:58  donn
8822861Smckusick  * Added Berkeley changes for subroutine call argument temporaries fix.
8922861Smckusick  *
9022861Smckusick  */
9122861Smckusick 
9222861Smckusick #include "defs.h"
9322861Smckusick 
9422861Smckusick #ifdef SDB
9522861Smckusick #	include <a.out.h>
9622861Smckusick #	ifndef N_SO
9722861Smckusick #		include <stab.h>
9822861Smckusick #	endif
9922861Smckusick #endif
10022861Smckusick 
10122861Smckusick extern flag namesflag;
10222861Smckusick 
10322861Smckusick typedef
10422861Smckusick   struct SizeList
10522861Smckusick     {
10622861Smckusick       struct SizeList *next;
10722861Smckusick       ftnint size;
10822861Smckusick       struct VarList *vars;
10922861Smckusick     }
11022861Smckusick   sizelist;
11122861Smckusick 
11222861Smckusick 
11322861Smckusick typedef
11422861Smckusick   struct VarList
11522861Smckusick     {
11622861Smckusick       struct VarList *next;
11722861Smckusick       Namep np;
11822861Smckusick       struct Equivblock *ep;
11922861Smckusick     }
12022861Smckusick   varlist;
12122861Smckusick 
12222861Smckusick 
12322861Smckusick LOCAL sizelist *varsizes;
12422861Smckusick 
12522861Smckusick 
12622861Smckusick /* start a new procedure */
12722861Smckusick 
12822861Smckusick newproc()
12922861Smckusick {
13022861Smckusick if(parstate != OUTSIDE)
13122861Smckusick 	{
13222861Smckusick 	execerr("missing end statement", CNULL);
13322861Smckusick 	endproc();
13422861Smckusick 	}
13522861Smckusick 
13622861Smckusick parstate = INSIDE;
13722861Smckusick procclass = CLMAIN;	/* default */
13822861Smckusick }
13922861Smckusick 
14022861Smckusick 
14122861Smckusick 
14222861Smckusick /* end of procedure. generate variables, epilogs, and prologs */
14322861Smckusick 
14422861Smckusick endproc()
14522861Smckusick {
14622861Smckusick struct Labelblock *lp;
14722861Smckusick 
14822861Smckusick if(parstate < INDATA)
14922861Smckusick 	enddcl();
15022861Smckusick if(ctlstack >= ctls)
15122861Smckusick 	err("DO loop or BLOCK IF not closed");
15222861Smckusick for(lp = labeltab ; lp < labtabend ; ++lp)
15322861Smckusick 	if(lp->stateno!=0 && lp->labdefined==NO)
15422861Smckusick 		errstr("missing statement number %s", convic(lp->stateno) );
15522861Smckusick 
15622861Smckusick if (optimflag)
15722861Smckusick   optimize();
15822861Smckusick 
15922861Smckusick outiodata();
16022861Smckusick epicode();
16122861Smckusick procode();
16222861Smckusick donmlist();
16322861Smckusick dobss();
16422861Smckusick 
16522861Smckusick #if FAMILY == PCC
16622861Smckusick 	putbracket();
16722861Smckusick #endif
16822861Smckusick fixlwm();
16922861Smckusick procinit();	/* clean up for next procedure */
17022861Smckusick }
17122861Smckusick 
17222861Smckusick 
17322861Smckusick 
17422861Smckusick /* End of declaration section of procedure.  Allocate storage. */
17522861Smckusick 
17622861Smckusick enddcl()
17722861Smckusick {
17822861Smckusick register struct Entrypoint *ep;
17922861Smckusick 
18022861Smckusick parstate = INEXEC;
18122861Smckusick docommon();
18222861Smckusick doequiv();
18322861Smckusick docomleng();
18422861Smckusick for(ep = entries ; ep ; ep = ep->entnextp) {
18522861Smckusick 	doentry(ep);
18622861Smckusick }
18722861Smckusick }
18822861Smckusick 
18922861Smckusick /* ROUTINES CALLED WHEN ENCOUNTERING ENTRY POINTS */
19022861Smckusick 
19122861Smckusick /* Main program or Block data */
19222861Smckusick 
19322861Smckusick startproc(prgname, class)
19422861Smckusick Namep prgname;
19522861Smckusick int class;
19622861Smckusick {
19722861Smckusick struct Extsym *progname;
19822861Smckusick register struct Entrypoint *p;
19922861Smckusick 
20022861Smckusick if(prgname)
20122861Smckusick 	procname = prgname->varname;
20222861Smckusick if(namesflag == YES) {
20322861Smckusick 	fprintf(diagfile, "   %s", (class==CLMAIN ? "MAIN" : "BLOCK DATA") );
20422861Smckusick 	if(prgname)
20522861Smckusick 		fprintf(diagfile, " %s", varstr(XL, procname) );
20622861Smckusick 	fprintf(diagfile, ":\n");
20722861Smckusick 	}
20822861Smckusick 
20922861Smckusick if( prgname )
21022861Smckusick 	progname = newentry( prgname );
21122861Smckusick else
21222861Smckusick 	progname = NULL;
21322861Smckusick 
21422861Smckusick p = ALLOC(Entrypoint);
21522861Smckusick if(class == CLMAIN)
21622861Smckusick 	puthead("MAIN_", CLMAIN);
21722861Smckusick else
21822861Smckusick 	puthead(CNULL, CLBLOCK);
21922861Smckusick if(class == CLMAIN)
22022861Smckusick 	newentry( mkname(5, "MAIN") );
22122861Smckusick p->entryname = progname;
22222861Smckusick p->entrylabel = newlabel();
22322861Smckusick entries = p;
22422861Smckusick 
22522861Smckusick procclass = class;
22622861Smckusick retlabel = newlabel();
22722861Smckusick #ifdef SDB
22822861Smckusick if(sdbflag) {
22922861Smckusick          entrystab(p,class);
23022861Smckusick }
23122861Smckusick #endif
23222861Smckusick }
23322861Smckusick 
23422861Smckusick /* subroutine or function statement */
23522861Smckusick 
23622861Smckusick struct Extsym *newentry(v)
23722861Smckusick register Namep v;
23822861Smckusick {
23922861Smckusick register struct Extsym *p;
24022861Smckusick 
24122861Smckusick p = mkext( varunder(VL, v->varname) );
24222861Smckusick 
24322861Smckusick if(p==NULL || p->extinit || ! ONEOF(p->extstg, M(STGUNKNOWN)|M(STGEXT)) )
24422861Smckusick 	{
24522861Smckusick 	if(p == 0)
24622861Smckusick 		dclerr("invalid entry name", v);
24722861Smckusick 	else	dclerr("external name already used", v);
24822861Smckusick 	return(0);
24922861Smckusick 	}
25022861Smckusick v->vstg = STGAUTO;
25122861Smckusick v->vprocclass = PTHISPROC;
25222861Smckusick v->vclass = CLPROC;
25322861Smckusick p->extstg = STGEXT;
25422861Smckusick p->extinit = YES;
25522861Smckusick return(p);
25622861Smckusick }
25722861Smckusick 
25822861Smckusick 
25922861Smckusick entrypt(class, type, length, entname, args)
26022861Smckusick int class, type;
26122861Smckusick ftnint length;
26222861Smckusick Namep entname;
26322861Smckusick chainp args;
26422861Smckusick {
26522861Smckusick struct Extsym *entry;
26622861Smckusick register Namep q;
26722861Smckusick register struct Entrypoint *p, *ep;
26822861Smckusick 
26922861Smckusick if(namesflag == YES) {
27022861Smckusick 	if(class == CLENTRY)
27122861Smckusick 		fprintf(diagfile, "       entry ");
27222861Smckusick 	if(entname)
27322861Smckusick 		fprintf(diagfile, "   %s", varstr(XL, entname->varname) );
27422861Smckusick 	fprintf(diagfile, ":\n");
27522861Smckusick 	}
27622861Smckusick 
27722861Smckusick if( entname->vclass == CLPARAM ) {
27822861Smckusick 	errstr("entry name %s used in 'parameter' statement",
27922861Smckusick 		varstr(XL, entname->varname) );
28022861Smckusick 	return;
28122861Smckusick 	}
28222861Smckusick if( ((type == TYSUBR) || (class == CLENTRY && proctype == TYSUBR))
28322861Smckusick 	&& (entname->vtype != TYUNKNOWN && entname->vtype != TYSUBR) ) {
28422861Smckusick 	errstr("subroutine entry %s previously declared",
28522861Smckusick 		varstr(XL, entname->varname) );
28622861Smckusick 	return;
28722861Smckusick 	}
28822861Smckusick if(  (entname->vstg != STGEXT && entname->vstg != STGUNKNOWN)
28922861Smckusick 	||  (entname->vdim != NULL) ) {
29022861Smckusick 	errstr("subroutine or function entry %s previously declared",
29122861Smckusick 		varstr(XL, entname->varname) );
29222861Smckusick 	return;
29322861Smckusick 	}
29422861Smckusick 
29522861Smckusick if( (class == CLPROC || class == CLENTRY) && type != TYSUBR )
29622861Smckusick 	/* arrange to save function return values */
29722861Smckusick 	entname->vsave = YES;
29822861Smckusick 
29922861Smckusick entry = newentry( entname );
30022861Smckusick 
30122861Smckusick if(class != CLENTRY)
30222861Smckusick 	puthead( varstr(XL, procname = entry->extname), class);
30322861Smckusick q = mkname(VL, nounder(XL,entry->extname) );
30422861Smckusick 
30522861Smckusick if( (type = lengtype(type, (int) length)) != TYCHAR)
30622861Smckusick 	length = 0;
30722861Smckusick if(class == CLPROC)
30822861Smckusick 	{
30922861Smckusick 	procclass = CLPROC;
31022861Smckusick 	proctype = type;
31122861Smckusick 	procleng = length;
31222861Smckusick 
31322861Smckusick 	retlabel = newlabel();
31422861Smckusick 	if(type == TYSUBR)
31522861Smckusick 		ret0label = newlabel();
31622861Smckusick 	}
31722861Smckusick 
31822861Smckusick p = ALLOC(Entrypoint);
31922861Smckusick if(entries)	/* put new block at end of entries list */
32022861Smckusick 	{
32122861Smckusick 	for(ep = entries; ep->entnextp; ep = ep->entnextp)
32222861Smckusick 		;
32322861Smckusick 	ep->entnextp = p;
32422861Smckusick 	}
32522861Smckusick else
32622861Smckusick 	entries = p;
32722861Smckusick 
32822861Smckusick p->entryname = entry;
32922861Smckusick p->arglist = args;
33022861Smckusick p->entrylabel = newlabel();
33122861Smckusick p->enamep = q;
33222861Smckusick 
33322861Smckusick if(class == CLENTRY)
33422861Smckusick 	{
33522861Smckusick 	class = CLPROC;
33622861Smckusick 	if(proctype == TYSUBR)
33722861Smckusick 		type = TYSUBR;
33822861Smckusick 	}
33922861Smckusick 
34022861Smckusick q->vclass = class;
34122861Smckusick q->vprocclass = PTHISPROC;
34222861Smckusick settype(q, type, (int) length);
34322861Smckusick /* hold all initial entry points till end of declarations */
34422861Smckusick if(parstate >= INDATA) {
34522861Smckusick 	doentry(p);
34622861Smckusick }
34722861Smckusick #ifdef SDB
34822861Smckusick 	if(sdbflag)
34922861Smckusick 	{ /* may need to preserve CLENTRY here */
35022861Smckusick 	entrystab(p,class);
35122861Smckusick 	}
35222861Smckusick #endif
35322861Smckusick }
35422861Smckusick 
35522861Smckusick /* generate epilogs */
35622861Smckusick 
35722861Smckusick LOCAL epicode()
35822861Smckusick {
35922861Smckusick register int i;
36022861Smckusick 
36122861Smckusick if(procclass==CLPROC)
36222861Smckusick 	{
36322861Smckusick 	if(proctype==TYSUBR)
36422861Smckusick 		{
36522861Smckusick 		putlabel(ret0label);
36622861Smckusick 		if(substars)
36722861Smckusick 			putforce(TYINT, ICON(0) );
36822861Smckusick 		putlabel(retlabel);
36922861Smckusick 		goret(TYSUBR);
37022861Smckusick 		}
37122861Smckusick 	else	{
37222861Smckusick 		putlabel(retlabel);
37322861Smckusick 		if(multitype)
37422861Smckusick 			{
37522861Smckusick 			typeaddr = autovar(1, TYADDR, PNULL);
37622861Smckusick 			putbranch( cpexpr(typeaddr) );
37722861Smckusick 			for(i = 0; i < NTYPES ; ++i)
37822861Smckusick 				if(rtvlabel[i] != 0)
37922861Smckusick 					{
38022861Smckusick 					putlabel(rtvlabel[i]);
38122861Smckusick 					retval(i);
38222861Smckusick 					}
38322861Smckusick 			}
38422861Smckusick 		else
38522861Smckusick 			retval(proctype);
38622861Smckusick 		}
38722861Smckusick 	}
38822861Smckusick 
38922861Smckusick else if(procclass != CLBLOCK)
39022861Smckusick 	{
39122861Smckusick 	putlabel(retlabel);
39222861Smckusick 	goret(TYSUBR);
39322861Smckusick 	}
39422861Smckusick }
39522861Smckusick 
39622861Smckusick 
39722861Smckusick /* generate code to return value of type  t */
39822861Smckusick 
39922861Smckusick LOCAL retval(t)
40022861Smckusick register int t;
40122861Smckusick {
40222861Smckusick register Addrp p;
40322861Smckusick 
40422861Smckusick switch(t)
40522861Smckusick 	{
40622861Smckusick 	case TYCHAR:
40722861Smckusick 	case TYCOMPLEX:
40822861Smckusick 	case TYDCOMPLEX:
40922861Smckusick 		break;
41022861Smckusick 
41122861Smckusick 	case TYLOGICAL:
41222861Smckusick 		t = tylogical;
41322861Smckusick 	case TYADDR:
41422861Smckusick 	case TYSHORT:
41522861Smckusick 	case TYLONG:
41622861Smckusick 		p = (Addrp) cpexpr(retslot);
41722861Smckusick 		p->vtype = t;
41822861Smckusick 		putforce(t, p);
41922861Smckusick 		break;
42022861Smckusick 
42122861Smckusick 	case TYREAL:
42222861Smckusick 	case TYDREAL:
42322861Smckusick 		p = (Addrp) cpexpr(retslot);
42422861Smckusick 		p->vtype = t;
42522861Smckusick 		putforce(t, p);
42622861Smckusick 		break;
42722861Smckusick 
428*23477Smckusick 	case TYERROR:
429*23477Smckusick 		return;		/* someone else already complained */
430*23477Smckusick 
43122861Smckusick 	default:
43222861Smckusick 		badtype("retval", t);
43322861Smckusick 	}
43422861Smckusick goret(t);
43522861Smckusick }
43622861Smckusick 
43722861Smckusick 
43822861Smckusick /* Allocate extra argument array if needed. Generate prologs. */
43922861Smckusick 
44022861Smckusick LOCAL procode()
44122861Smckusick {
44222861Smckusick register struct Entrypoint *p;
44322861Smckusick Addrp argvec;
44422861Smckusick 
44522861Smckusick #if TARGET==GCOS
44622861Smckusick 	argvec = autovar(lastargslot/SZADDR, TYADDR, PNULL);
44722861Smckusick #else
44822861Smckusick 	if(lastargslot>0 && nentry>1)
44922861Smckusick #if TARGET == VAX
45022861Smckusick 		argvec = autovar(1 + lastargslot/SZADDR, TYADDR, PNULL);
45122861Smckusick #else
45222861Smckusick 		argvec = autovar(lastargslot/SZADDR, TYADDR, PNULL);
45322861Smckusick #endif
45422861Smckusick 	else
45522861Smckusick 		argvec = NULL;
45622861Smckusick #endif
45722861Smckusick 
45822861Smckusick 
45922861Smckusick #if TARGET == PDP11
46022861Smckusick 	/* for the optimizer */
46122861Smckusick 	if(fudgelabel)
46222861Smckusick 		putlabel(fudgelabel);
46322861Smckusick #endif
46422861Smckusick 
46522861Smckusick for(p = entries ; p ; p = p->entnextp)
46622861Smckusick 	prolog(p, argvec);
46722861Smckusick 
46822861Smckusick #if FAMILY == PCC
46922861Smckusick 	putrbrack(procno);
47022861Smckusick #endif
47122861Smckusick 
47222861Smckusick prendproc();
47322861Smckusick }
47422861Smckusick 
47522861Smckusick 
47622861Smckusick /*
47722861Smckusick    manipulate argument lists (allocate argument slot positions)
47822861Smckusick  * keep track of return types and labels
47922861Smckusick  */
48022861Smckusick 
48122861Smckusick LOCAL doentry(ep)
48222861Smckusick struct Entrypoint *ep;
48322861Smckusick {
48422861Smckusick register int type;
48522861Smckusick register Namep np;
48622861Smckusick chainp p;
48722861Smckusick register Namep q;
48822861Smckusick Addrp mkarg();
48922861Smckusick 
49022861Smckusick ++nentry;
49122861Smckusick if(procclass == CLMAIN)
49222861Smckusick 	{
49322861Smckusick 	if (optimflag)
49422861Smckusick 		optbuff (SKLABEL, 0, ep->entrylabel, 0);
49522861Smckusick 	else
49622861Smckusick 		putlabel(ep->entrylabel);
49722861Smckusick 	return;
49822861Smckusick 	}
49922861Smckusick else if(procclass == CLBLOCK)
50022861Smckusick 	return;
50122861Smckusick 
50222861Smckusick impldcl( np = mkname(VL, nounder(XL, ep->entryname->extname) ) );
50322861Smckusick type = np->vtype;
50422861Smckusick if(proctype == TYUNKNOWN)
50522861Smckusick 	if( (proctype = type) == TYCHAR)
50622861Smckusick 		procleng = (np->vleng ? np->vleng->constblock.const.ci : (ftnint) (-1));
50722861Smckusick 
50822861Smckusick if(proctype == TYCHAR)
50922861Smckusick 	{
51022861Smckusick 	if(type != TYCHAR)
51122861Smckusick 		err("noncharacter entry of character function");
51222861Smckusick 	else if( (np->vleng ? np->vleng->constblock.const.ci : (ftnint) (-1)) != procleng)
51322861Smckusick 		err("mismatched character entry lengths");
51422861Smckusick 	}
51522861Smckusick else if(type == TYCHAR)
51622861Smckusick 	err("character entry of noncharacter function");
51722861Smckusick else if(type != proctype)
51822861Smckusick 	multitype = YES;
51922861Smckusick if(rtvlabel[type] == 0)
52022861Smckusick 	rtvlabel[type] = newlabel();
52122861Smckusick ep->typelabel = rtvlabel[type];
52222861Smckusick 
52322861Smckusick if(type == TYCHAR)
52422861Smckusick 	{
52522861Smckusick 	if(chslot < 0)
52622861Smckusick 		{
52722861Smckusick 		chslot = nextarg(TYADDR);
52822861Smckusick 		chlgslot = nextarg(TYLENG);
52922861Smckusick 		}
53022861Smckusick 	np->vstg = STGARG;
53122861Smckusick 	np->vardesc.varno = chslot;
53222861Smckusick 	if(procleng < 0)
53322861Smckusick 		np->vleng = (expptr) mkarg(TYLENG, chlgslot);
53422861Smckusick 	}
53522861Smckusick else if( ISCOMPLEX(type) )
53622861Smckusick 	{
53722861Smckusick 	np->vstg = STGARG;
53822861Smckusick 	if(cxslot < 0)
53922861Smckusick 		cxslot = nextarg(TYADDR);
54022861Smckusick 	np->vardesc.varno = cxslot;
54122861Smckusick 	}
54222861Smckusick else if(type != TYSUBR)
54322861Smckusick 	{
54422861Smckusick 	if(retslot == NULL)
54522861Smckusick 		retslot = autovar(1, TYDREAL, PNULL);
54622861Smckusick 	np->vstg = STGAUTO;
54722861Smckusick 	np->voffset = retslot->memoffset->constblock.const.ci;
54822861Smckusick 	}
54922861Smckusick 
55022861Smckusick for(p = ep->arglist ; p ; p = p->nextp)
55122861Smckusick 	if(! (( q = (Namep) (p->datap) )->vdcldone) )
55222861Smckusick 		q->vardesc.varno = nextarg(TYADDR);
55322861Smckusick 
55422861Smckusick for(p = ep->arglist ; p ; p = p->nextp)
55522861Smckusick 	if(! (( q = (Namep) (p->datap) )->vdcldone) )
55622861Smckusick 		{
55722861Smckusick 		impldcl(q);
55822861Smckusick 		q->vdcldone = YES;
55922861Smckusick 		if(q->vtype == TYCHAR)
56022861Smckusick 			{
56122861Smckusick 			if(q->vleng == NULL)	/* character*(*) */
56222861Smckusick 				q->vleng = (expptr)
56322861Smckusick 						mkarg(TYLENG, nextarg(TYLENG) );
56422861Smckusick 			else if(nentry == 1)
56522861Smckusick 				nextarg(TYLENG);
56622861Smckusick 			}
56722861Smckusick 		else if(q->vclass==CLPROC && nentry==1)
56822861Smckusick 			nextarg(TYLENG) ;
56922861Smckusick #ifdef SDB
57022861Smckusick 		if(sdbflag) {
57122861Smckusick 			namestab(q);
57222861Smckusick 		}
57322861Smckusick #endif
57422861Smckusick 		}
57522861Smckusick 
57622861Smckusick if (optimflag)
57722861Smckusick 	optbuff (SKLABEL, 0, ep->entrylabel, 0);
57822861Smckusick else
57922861Smckusick 	putlabel(ep->entrylabel);
58022861Smckusick }
58122861Smckusick 
58222861Smckusick 
58322861Smckusick 
58422861Smckusick LOCAL nextarg(type)
58522861Smckusick int type;
58622861Smckusick {
58722861Smckusick int k;
58822861Smckusick k = lastargslot;
58922861Smckusick lastargslot += typesize[type];
59022861Smckusick return(k);
59122861Smckusick }
59222861Smckusick 
59322861Smckusick /* generate variable references */
59422861Smckusick 
59522861Smckusick LOCAL dobss()
59622861Smckusick {
59722861Smckusick register struct Hashentry *p;
59822861Smckusick register Namep q;
59922861Smckusick register int i;
60022861Smckusick int align;
60122861Smckusick ftnint leng, iarrl;
60222861Smckusick char *memname();
60322861Smckusick int qstg, qclass, qtype;
60422861Smckusick 
60522861Smckusick pruse(asmfile, USEBSS);
60622861Smckusick varsizes = NULL;
60722861Smckusick 
60822861Smckusick for(p = hashtab ; p<lasthash ; ++p)
60922861Smckusick     if(q = p->varp)
61022861Smckusick 	{
61122861Smckusick 	qstg = q->vstg;
61222861Smckusick 	qtype = q->vtype;
61322861Smckusick 	qclass = q->vclass;
61422861Smckusick 
61522861Smckusick 	if( (qclass==CLUNKNOWN && qstg!=STGARG) ||
61622861Smckusick 	    (qclass==CLVAR && qstg==STGUNKNOWN) )
61722861Smckusick 		warn1("local variable %s never used", varstr(VL,q->varname) );
61822861Smckusick 	else if(qclass==CLPROC && q->vprocclass==PEXTERNAL && qstg!=STGARG)
61922861Smckusick 		mkext(varunder(VL, q->varname)) ->extstg = STGEXT;
62022861Smckusick 
62122861Smckusick 	if (qclass == CLVAR && qstg == STGBSS)
62222861Smckusick 	  {
62322861Smckusick 	    if (SMALLVAR(q->varsize))
62422861Smckusick 	      {
62522861Smckusick 		enlist(q->varsize, q, NULL);
62622861Smckusick 		q->inlcomm = NO;
62722861Smckusick 	      }
62822861Smckusick 	    else
62922861Smckusick 	      {
63022861Smckusick 		if (q->init == NO)
63122861Smckusick 		  {
63222861Smckusick 		    preven(ALIDOUBLE);
63322861Smckusick 		    prlocvar(memname(qstg, q->vardesc.varno), q->varsize);
63422861Smckusick 		    q->inlcomm = YES;
63522861Smckusick 		  }
63622861Smckusick 		else
63722861Smckusick 		  prlocdata(memname(qstg, q->vardesc.varno), q->varsize,
63822861Smckusick 			    q->vtype, q->initoffset, &(q->inlcomm));
63922861Smckusick 	      }
64022861Smckusick 	  }
64122861Smckusick 	else if(qclass==CLVAR && qstg!=STGARG)
64222861Smckusick 		{
64322861Smckusick 		if(q->vdim && !ISICON(q->vdim->nelt) )
64422861Smckusick 			dclerr("adjustable dimension on non-argument", q);
64522861Smckusick 		if(qtype==TYCHAR && (q->vleng==NULL || !ISICON(q->vleng)))
64622861Smckusick 			dclerr("adjustable leng on nonargument", q);
64722861Smckusick 		}
64822861Smckusick 
64922861Smckusick 	chkdim(q);
65022861Smckusick 	}
65122861Smckusick 
65222861Smckusick for (i = 0 ; i < nequiv ; ++i)
65322861Smckusick   if ( (leng = eqvclass[i].eqvleng) != 0 )
65422861Smckusick     {
65522861Smckusick       if (SMALLVAR(leng))
65622861Smckusick 	enlist(leng, NULL, eqvclass + i);
65722861Smckusick       else if (eqvclass[i].init == NO)
65822861Smckusick 	{
65922861Smckusick 	  preven(ALIDOUBLE);
66022861Smckusick 	  prlocvar(memname(STGEQUIV, i), leng);
66122861Smckusick 	  eqvclass[i].inlcomm = YES;
66222861Smckusick 	}
66322861Smckusick       else
66422861Smckusick 	prlocdata(memname(STGEQUIV, i), leng, TYDREAL,
66522861Smckusick 		  eqvclass[i].initoffset, &(eqvclass[i].inlcomm));
66622861Smckusick     }
66722861Smckusick 
66822861Smckusick   outlocvars();
66922861Smckusick #ifdef SDB
67022861Smckusick     if(sdbflag) {
67122861Smckusick       for(p = hashtab ; p<lasthash ; ++p) if(q = p->varp) {
67222861Smckusick 	  qstg = q->vstg;
67322861Smckusick 	  qclass = q->vclass;
67422861Smckusick           if( ONEOF(qclass, M(CLVAR))) {
67522861Smckusick 	     if (! ONEOF(qstg,M(STGCOMMON)|M(STGARG) ) ) namestab(q);
67622861Smckusick 	  }
67722861Smckusick       }
67822861Smckusick     }
67922861Smckusick #endif
68022861Smckusick 
68122861Smckusick   close(vdatafile);
68222861Smckusick   close(vchkfile);
68322861Smckusick   unlink(vdatafname);
68422861Smckusick   unlink(vchkfname);
68522861Smckusick   vdatahwm = 0;
68622861Smckusick }
68722861Smckusick 
68822861Smckusick 
68922861Smckusick 
69022861Smckusick donmlist()
69122861Smckusick {
69222861Smckusick register struct Hashentry *p;
69322861Smckusick register Namep q;
69422861Smckusick 
69522861Smckusick pruse(asmfile, USEINIT);
69622861Smckusick 
69722861Smckusick for(p=hashtab; p<lasthash; ++p)
69822861Smckusick 	if( (q = p->varp) && q->vclass==CLNAMELIST)
69922861Smckusick 		namelist(q);
70022861Smckusick }
70122861Smckusick 
70222861Smckusick 
70322861Smckusick doext()
70422861Smckusick {
70522861Smckusick struct Extsym *p;
70622861Smckusick 
70722861Smckusick for(p = extsymtab ; p<nextext ; ++p)
70822861Smckusick 	prext(p);
70922861Smckusick }
71022861Smckusick 
71122861Smckusick 
71222861Smckusick 
71322861Smckusick 
71422861Smckusick ftnint iarrlen(q)
71522861Smckusick register Namep q;
71622861Smckusick {
71722861Smckusick ftnint leng;
71822861Smckusick 
71922861Smckusick leng = typesize[q->vtype];
72022861Smckusick if(leng <= 0)
72122861Smckusick 	return(-1);
72222861Smckusick if(q->vdim)
72322861Smckusick 	if( ISICON(q->vdim->nelt) )
72422861Smckusick 		leng *= q->vdim->nelt->constblock.const.ci;
72522861Smckusick 	else	return(-1);
72622861Smckusick if(q->vleng)
72722861Smckusick 	if( ISICON(q->vleng) )
72822861Smckusick 		leng *= q->vleng->constblock.const.ci;
72922861Smckusick 	else 	return(-1);
73022861Smckusick return(leng);
73122861Smckusick }
73222861Smckusick 
73322861Smckusick /* This routine creates a static block representing the namelist.
73422861Smckusick    An equivalent declaration of the structure produced is:
73522861Smckusick 	struct namelist
73622861Smckusick 		{
73722861Smckusick 		char namelistname[16];
73822861Smckusick 		struct namelistentry
73922861Smckusick 			{
74022861Smckusick 			char varname[16];
74122861Smckusick 			char *varaddr;
74222861Smckusick 			int type; # negative means -type= number of chars
74322861Smckusick 			struct dimensions *dimp; # null means scalar
74422861Smckusick 			} names[];
74522861Smckusick 		};
74622861Smckusick 
74722861Smckusick 	struct dimensions
74822861Smckusick 		{
74922861Smckusick 		int numberofdimensions;
75022861Smckusick 		int numberofelements
75122861Smckusick 		int baseoffset;
75222861Smckusick 		int span[numberofdimensions];
75322861Smckusick 		};
75422861Smckusick    where the namelistentry list terminates with a null varname
75522861Smckusick    If dimp is not null, then the corner element of the array is at
75622861Smckusick    varaddr.  However,  the element with subscripts (i1,...,in) is at
75722861Smckusick    varaddr - dimp->baseoffset + sizeoftype * (i1+span[0]*(i2+span[1]*...)
75822861Smckusick */
75922861Smckusick 
76022861Smckusick namelist(np)
76122861Smckusick Namep np;
76222861Smckusick {
76322861Smckusick register chainp q;
76422861Smckusick register Namep v;
76522861Smckusick register struct Dimblock *dp;
76622861Smckusick char *memname();
76722861Smckusick int type, dimno, dimoffset;
76822861Smckusick flag bad;
76922861Smckusick 
77022861Smckusick 
77122861Smckusick preven(ALILONG);
77222861Smckusick fprintf(asmfile, LABELFMT, memname(STGINIT, np->vardesc.varno));
77322861Smckusick putstr(asmfile, varstr(VL, np->varname), 16);
77422861Smckusick dimno = ++lastvarno;
77522861Smckusick dimoffset = 0;
77622861Smckusick bad = NO;
77722861Smckusick 
77822861Smckusick for(q = np->varxptr.namelist ; q ; q = q->nextp)
77922861Smckusick 	{
78022861Smckusick 	vardcl( v = (Namep) (q->datap) );
78122861Smckusick 	type = v->vtype;
78222861Smckusick 	if( ONEOF(v->vstg, MSKSTATIC) )
78322861Smckusick 		{
78422861Smckusick 		preven(ALILONG);
78522861Smckusick 		putstr(asmfile, varstr(VL,v->varname), 16);
78622861Smckusick 		praddr(asmfile, v->vstg, v->vardesc.varno, v->voffset);
78722861Smckusick 		prconi(asmfile, TYINT,
78822861Smckusick 			type==TYCHAR ?
78922861Smckusick 			    -(v->vleng->constblock.const.ci) : (ftnint) type);
79022861Smckusick 		if(v->vdim)
79122861Smckusick 			{
79222861Smckusick 			praddr(asmfile, STGINIT, dimno, (ftnint)dimoffset);
79322861Smckusick 			dimoffset += 3 + v->vdim->ndim;
79422861Smckusick 			}
79522861Smckusick 		else
79622861Smckusick 			praddr(asmfile, STGNULL,0,(ftnint) 0);
79722861Smckusick 		}
79822861Smckusick 	else
79922861Smckusick 		{
80022861Smckusick 		dclerr("may not appear in namelist", v);
80122861Smckusick 		bad = YES;
80222861Smckusick 		}
80322861Smckusick 	}
80422861Smckusick 
80522861Smckusick if(bad)
80622861Smckusick 	return;
80722861Smckusick 
80822861Smckusick putstr(asmfile, "", 16);
80922861Smckusick 
81022861Smckusick if(dimoffset > 0)
81122861Smckusick 	{
81222861Smckusick 	fprintf(asmfile, LABELFMT, memname(STGINIT,dimno));
81322861Smckusick 	for(q = np->varxptr.namelist ; q ; q = q->nextp)
81422861Smckusick 		if(dp = q->datap->nameblock.vdim)
81522861Smckusick 			{
81622861Smckusick 			int i;
81722861Smckusick 			prconi(asmfile, TYINT, (ftnint) (dp->ndim) );
81822861Smckusick 			prconi(asmfile, TYINT,
81922861Smckusick 				(ftnint) (dp->nelt->constblock.const.ci) );
82022861Smckusick 			prconi(asmfile, TYINT,
82122861Smckusick 				(ftnint) (dp->baseoffset->constblock.const.ci));
82222861Smckusick 			for(i=0; i<dp->ndim ; ++i)
82322861Smckusick 				prconi(asmfile, TYINT,
82422861Smckusick 					dp->dims[i].dimsize->constblock.const.ci);
82522861Smckusick 			}
82622861Smckusick 	}
82722861Smckusick 
82822861Smckusick }
82922861Smckusick 
83022861Smckusick LOCAL docommon()
83122861Smckusick {
83222861Smckusick register struct Extsym *p;
83322861Smckusick register chainp q;
83422861Smckusick struct Dimblock *t;
83522861Smckusick expptr neltp;
83622861Smckusick register Namep v;
83722861Smckusick ftnint size;
83822861Smckusick int type;
83922861Smckusick 
84022861Smckusick for(p = extsymtab ; p<nextext ; ++p)
84122861Smckusick 	if(p->extstg==STGCOMMON)
84222861Smckusick 		{
84322861Smckusick #ifdef SDB
84422861Smckusick 		if(sdbflag)
84522861Smckusick 			prstab(varstr(XL,p->extname), N_BCOMM, 0, 0);
84622861Smckusick #endif
84722861Smckusick 		for(q = p->extp ; q ; q = q->nextp)
84822861Smckusick 			{
84922861Smckusick 			v = (Namep) (q->datap);
85022861Smckusick 			if(v->vdcldone == NO)
85122861Smckusick 				vardcl(v);
85222861Smckusick 			type = v->vtype;
85322861Smckusick 			if(p->extleng % typealign[type] != 0)
85422861Smckusick 				{
85522861Smckusick 				dclerr("common alignment", v);
85622861Smckusick 				p->extleng = roundup(p->extleng, typealign[type]);
85722861Smckusick 				}
85822861Smckusick 			v->voffset = p->extleng;
85922861Smckusick 			v->vardesc.varno = p - extsymtab;
86022861Smckusick 			if(type == TYCHAR)
86122861Smckusick 				size = v->vleng->constblock.const.ci;
86222861Smckusick 			else	size = typesize[type];
86322861Smckusick 			if(t = v->vdim)
86422861Smckusick 				if( (neltp = t->nelt) && ISCONST(neltp) )
86522861Smckusick 					size *= neltp->constblock.const.ci;
86622861Smckusick 				else
86722861Smckusick 					dclerr("adjustable array in common", v);
86822861Smckusick 			p->extleng += size;
86922861Smckusick #ifdef SDB
87022861Smckusick 			if(sdbflag)
87122861Smckusick 				{
87222861Smckusick 				namestab(v);
87322861Smckusick 				}
87422861Smckusick #endif
87522861Smckusick 			}
87622861Smckusick 
87722861Smckusick 		frchain( &(p->extp) );
87822861Smckusick #ifdef SDB
87922861Smckusick 		if(sdbflag)
88022861Smckusick 			prstab(varstr(XL,p->extname), N_ECOMM, 0, 0);
88122861Smckusick #endif
88222861Smckusick 		}
88322861Smckusick }
88422861Smckusick 
88522861Smckusick 
88622861Smckusick 
88722861Smckusick 
88822861Smckusick 
88922861Smckusick LOCAL docomleng()
89022861Smckusick {
89122861Smckusick register struct Extsym *p;
89222861Smckusick 
89322861Smckusick for(p = extsymtab ; p < nextext ; ++p)
89422861Smckusick 	if(p->extstg == STGCOMMON)
89522861Smckusick 		{
89622861Smckusick 		if(p->maxleng!=0 && p->extleng!=0 && p->maxleng!=p->extleng
89722861Smckusick 		    && !eqn(XL,"_BLNK__ ",p->extname) )
89822861Smckusick 			warn1("incompatible lengths for common block %s",
89922861Smckusick 				nounder(XL, p->extname) );
90022861Smckusick 		if(p->maxleng < p->extleng)
90122861Smckusick 			p->maxleng = p->extleng;
90222861Smckusick 		p->extleng = 0;
90322861Smckusick 	}
90422861Smckusick }
90522861Smckusick 
90622861Smckusick 
90722861Smckusick 
90822861Smckusick 
90922861Smckusick /* ROUTINES DEALING WITH AUTOMATIC AND TEMPORARY STORAGE */
91022861Smckusick 
91122861Smckusick /*  frees a temporary block  */
91222861Smckusick 
91322861Smckusick frtemp(p)
91422861Smckusick Tempp p;
91522861Smckusick {
91622861Smckusick Addrp t;
91722861Smckusick 
91822861Smckusick if (optimflag)
91922861Smckusick 	{
92022861Smckusick 	if (p->tag != TTEMP)
92122861Smckusick 		badtag ("frtemp",p->tag);
92222861Smckusick 	t = p->memalloc;
92322861Smckusick 	}
92422861Smckusick else
92522861Smckusick 	t = (Addrp) p;
92622861Smckusick 
92722861Smckusick /* restore clobbered character string lengths */
92822861Smckusick if(t->vtype==TYCHAR && t->varleng!=0)
92922861Smckusick 	{
93022861Smckusick 	frexpr(t->vleng);
93122861Smckusick 	t->vleng = ICON(t->varleng);
93222861Smckusick 	}
93322861Smckusick 
93422861Smckusick /* put block on chain of temps to be reclaimed */
93522861Smckusick holdtemps = mkchain(t, holdtemps);
93622861Smckusick }
93722861Smckusick 
93822861Smckusick 
93922861Smckusick 
94022861Smckusick /* allocate an automatic variable slot */
94122861Smckusick 
94222861Smckusick Addrp autovar(nelt, t, lengp)
94322861Smckusick register int nelt, t;
94422861Smckusick expptr lengp;
94522861Smckusick {
94622861Smckusick ftnint leng;
94722861Smckusick register Addrp q;
94822861Smckusick 
94922861Smckusick if(lengp)
95022861Smckusick 	if( ISICON(lengp) )
95122861Smckusick 		leng = lengp->constblock.const.ci;
95222861Smckusick 	else	{
95322861Smckusick 		fatal("automatic variable of nonconstant length");
95422861Smckusick 		}
95522861Smckusick else
95622861Smckusick 	leng = typesize[t];
95722861Smckusick autoleng = roundup( autoleng, typealign[t]);
95822861Smckusick 
95922861Smckusick q = ALLOC(Addrblock);
96022861Smckusick q->tag = TADDR;
96122861Smckusick q->vtype = t;
96222861Smckusick if(lengp)
96322861Smckusick 	{
96422861Smckusick 	q->vleng = ICON(leng);
96522861Smckusick 	q->varleng = leng;
96622861Smckusick 	}
96722861Smckusick q->vstg = STGAUTO;
96822861Smckusick q->memno = newlabel();
96922861Smckusick q->ntempelt = nelt;
97022861Smckusick #if TARGET==PDP11 || TARGET==VAX
97122861Smckusick 	/* stack grows downward */
97222861Smckusick 	autoleng += nelt*leng;
97322861Smckusick 	q->memoffset = ICON( - autoleng );
97422861Smckusick #else
97522861Smckusick 	q->memoffset = ICON( autoleng );
97622861Smckusick 	autoleng += nelt*leng;
97722861Smckusick #endif
97822861Smckusick 
97922861Smckusick return(q);
98022861Smckusick }
98122861Smckusick 
98222861Smckusick 
98322861Smckusick 
98422861Smckusick /*
98522861Smckusick  *  create a temporary block (TTEMP) when optimizing,
98622861Smckusick  *  an ordinary TADDR block when not optimizing
98722861Smckusick  */
98822861Smckusick 
98922861Smckusick Tempp mktmpn(nelt, type, lengp)
99022861Smckusick int nelt;
99122861Smckusick register int type;
99222861Smckusick expptr lengp;
99322861Smckusick {
99422861Smckusick ftnint leng;
99522861Smckusick chainp p, oldp;
99622861Smckusick register Tempp q;
99722861Smckusick Addrp altemp;
99822861Smckusick 
99922861Smckusick if (! optimflag)
100022861Smckusick 	return ( (Tempp) mkaltmpn(nelt,type,lengp) );
100122861Smckusick if(type==TYUNKNOWN || type==TYERROR)
100222861Smckusick 	badtype("mktmpn", type);
100322861Smckusick 
100422861Smckusick if(type==TYCHAR)
100522861Smckusick 	if( ISICON(lengp) )
100622861Smckusick 		leng = lengp->constblock.const.ci;
100722861Smckusick 	else	{
100822861Smckusick 		err("adjustable length");
100922861Smckusick 		return( (Tempp) errnode() );
101022861Smckusick 		}
101122861Smckusick else
101222861Smckusick 	leng = typesize[type];
101322861Smckusick 
101422861Smckusick q = ALLOC(Tempblock);
101522861Smckusick q->tag = TTEMP;
101622861Smckusick q->vtype = type;
101722861Smckusick if(type == TYCHAR)
101822861Smckusick 	{
101922861Smckusick 	q->vleng = ICON(leng);
102022861Smckusick 	q->varleng = leng;
102122861Smckusick 	}
102222861Smckusick 
102322861Smckusick altemp = ALLOC(Addrblock);
102422861Smckusick altemp->tag = TADDR;
102522861Smckusick altemp->vstg = STGUNKNOWN;
102622861Smckusick q->memalloc = altemp;
102722861Smckusick 
102822861Smckusick q->ntempelt = nelt;
102922861Smckusick q->istemp = YES;
103022861Smckusick return(q);
103122861Smckusick }
103222861Smckusick 
103322861Smckusick 
103422861Smckusick 
103522861Smckusick Addrp mktemp(type, lengp)
103622861Smckusick int type;
103722861Smckusick expptr lengp;
103822861Smckusick {
103922861Smckusick return( (Addrp) mktmpn(1,type,lengp) );
104022861Smckusick }
104122861Smckusick 
104222861Smckusick 
104322861Smckusick 
104422861Smckusick /*  allocate a temporary location for the given temporary block;
104522861Smckusick     if already allocated, return its location  */
104622861Smckusick 
104722861Smckusick Addrp altmpn(tp)
104822861Smckusick Tempp tp;
104922861Smckusick 
105022861Smckusick {
105122861Smckusick Addrp t, q;
105222861Smckusick 
105322861Smckusick if (tp->tag != TTEMP)
105422861Smckusick 	badtag ("altmpn",tp->tag);
105522861Smckusick 
105622861Smckusick t = tp->memalloc;
105722861Smckusick if (t->vstg != STGUNKNOWN)
105822861Smckusick 	{
105922861Smckusick 	if (tp->vtype == TYCHAR)
106022861Smckusick 		{
106122861Smckusick 		/*
106222861Smckusick 		 * Unformatted I/O parameters are treated like character
106322861Smckusick 		 *	strings (sigh) -- propagate type and length.
106422861Smckusick 		 */
106522861Smckusick 		t = (Addrp) cpexpr(t);
106622861Smckusick 		t->vtype = tp->vtype;
106722861Smckusick 		t->vleng = tp->vleng;
106822861Smckusick 		t->varleng = tp->varleng;
106922861Smckusick 		}
107022861Smckusick 	return (t);
107122861Smckusick 	}
107222861Smckusick 
107322861Smckusick q = mkaltmpn (tp->ntempelt, tp->vtype, tp->vleng);
107422861Smckusick cpn (sizeof(struct Addrblock), (char*)q, (char*)t);
107522861Smckusick free ( (charptr) q);
107622861Smckusick return(t);
107722861Smckusick }
107822861Smckusick 
107922861Smckusick 
108022861Smckusick 
108122861Smckusick /*  create and allocate space immediately for a temporary  */
108222861Smckusick 
108322861Smckusick Addrp mkaltemp(type,lengp)
108422861Smckusick int type;
108522861Smckusick expptr lengp;
108622861Smckusick {
108722861Smckusick return (mkaltmpn(1,type,lengp));
108822861Smckusick }
108922861Smckusick 
109022861Smckusick 
109122861Smckusick 
109222861Smckusick Addrp mkaltmpn(nelt,type,lengp)
109322861Smckusick int nelt;
109422861Smckusick register int type;
109522861Smckusick expptr lengp;
109622861Smckusick {
109722861Smckusick ftnint leng;
109822861Smckusick chainp p, oldp;
109922861Smckusick register Addrp q;
110022861Smckusick 
110122861Smckusick if(type==TYUNKNOWN || type==TYERROR)
110222861Smckusick 	badtype("mkaltmpn", type);
110322861Smckusick 
110422861Smckusick if(type==TYCHAR)
110522861Smckusick 	if( ISICON(lengp) )
110622861Smckusick 		leng = lengp->constblock.const.ci;
110722861Smckusick 	else	{
110822861Smckusick 		err("adjustable length");
110922861Smckusick 		return( (Addrp) errnode() );
111022861Smckusick 		}
111122861Smckusick 
111222861Smckusick /*
111322861Smckusick  * if a temporary of appropriate shape is on the templist,
111422861Smckusick  * remove it from the list and return it
111522861Smckusick  */
111622861Smckusick 
111722861Smckusick #ifdef notdef
111822861Smckusick /*
111922861Smckusick  * This code is broken until SKFRTEMP slots can be processed in putopt()
112022861Smckusick  *	instead of in optimize() -- all kinds of things in putpcc.c can
112122861Smckusick  *	bomb because of this.  Sigh.
112222861Smckusick  */
112322861Smckusick for(oldp=CHNULL, p=templist  ;  p  ;  oldp=p, p=p->nextp)
112422861Smckusick 	{
112522861Smckusick 	q = (Addrp) (p->datap);
112622861Smckusick 	if(q->vtype==type && q->ntempelt==nelt &&
112722861Smckusick 	    (type!=TYCHAR || q->vleng->constblock.const.ci==leng) )
112822861Smckusick 		{
112922861Smckusick 		if(oldp)
113022861Smckusick 			oldp->nextp = p->nextp;
113122861Smckusick 		else
113222861Smckusick 			templist = p->nextp;
113322861Smckusick 		free( (charptr) p);
113422861Smckusick 
113522861Smckusick 		if (debugflag[14])
113622861Smckusick 			fprintf(diagfile,"mkaltmpn reusing offset %d\n",
113722861Smckusick 				q->memoffset->constblock.const.ci);
113822861Smckusick 		return(q);
113922861Smckusick 		}
114022861Smckusick 	}
114122861Smckusick #endif notdef
114222861Smckusick q = autovar(nelt, type, lengp);
114322861Smckusick q->istemp = YES;
114422861Smckusick 
114522861Smckusick if (debugflag[14])
114622861Smckusick 	fprintf(diagfile,"mkaltmpn new offset %d\n",
114722861Smckusick 		q->memoffset->constblock.const.ci);
114822861Smckusick return(q);
114922861Smckusick }
115022861Smckusick 
115122861Smckusick 
115222861Smckusick 
115322861Smckusick /*  The following routine is a patch which is only needed because the	*/
115422861Smckusick /*  code for processing actual arguments for calls does not allocate	*/
115522861Smckusick /*  the temps it needs before optimization takes place.  A better	*/
115622861Smckusick /*  solution is possible, but I do not have the time to implement it	*/
115722861Smckusick /*  now.								*/
115822861Smckusick /*									*/
115922861Smckusick /*					Robert P. Corbett		*/
116022861Smckusick 
116122861Smckusick Addrp
116222861Smckusick mkargtemp(type, lengp)
116322861Smckusick int type;
116422861Smckusick expptr lengp;
116522861Smckusick {
116622861Smckusick   ftnint leng;
116722861Smckusick   chainp oldp, p;
116822861Smckusick   Addrp q;
116922861Smckusick 
117022861Smckusick   if (type == TYUNKNOWN || type == TYERROR)
117122861Smckusick     badtype("mkargtemp", type);
117222861Smckusick 
117322861Smckusick   if (type == TYCHAR)
117422861Smckusick     {
117522861Smckusick       if (ISICON(lengp))
117622861Smckusick 	leng = lengp->constblock.const.ci;
117722861Smckusick       else
117822861Smckusick 	{
117922861Smckusick 	  err("adjustable length");
118022861Smckusick 	  return ((Addrp) errnode());
118122861Smckusick 	}
118222861Smckusick     }
118322861Smckusick 
118422861Smckusick   oldp = CHNULL;
118522861Smckusick   p = argtemplist;
118622861Smckusick 
118722861Smckusick   while (p)
118822861Smckusick     {
118922861Smckusick       q = (Addrp) (p->datap);
119022861Smckusick       if (q->vtype == type
119122861Smckusick 	  && (type != TYCHAR || q->vleng->constblock.const.ci == leng))
119222861Smckusick 	{
119322861Smckusick 	  if (oldp)
119422861Smckusick 	    oldp->nextp = p->nextp;
119522861Smckusick 	  else
119622861Smckusick 	    argtemplist = p->nextp;
119722861Smckusick 
119822861Smckusick 	  p->nextp = activearglist;
119922861Smckusick 	  activearglist = p;
120022861Smckusick 
120122861Smckusick 	  return ((Addrp) cpexpr(q));
120222861Smckusick 	}
120322861Smckusick 
120422861Smckusick       oldp = p;
120522861Smckusick       p = p->nextp;
120622861Smckusick     }
120722861Smckusick 
120822861Smckusick   q = autovar(1, type, lengp);
120922861Smckusick   activearglist = mkchain(q, activearglist);
121022861Smckusick   return ((Addrp) cpexpr(q));
121122861Smckusick }
121222861Smckusick 
121322861Smckusick /* VARIOUS ROUTINES FOR PROCESSING DECLARATIONS */
121422861Smckusick 
121522861Smckusick struct Extsym *comblock(len, s)
121622861Smckusick register int len;
121722861Smckusick register char *s;
121822861Smckusick {
121922861Smckusick struct Extsym *p;
122022861Smckusick 
122122861Smckusick if(len == 0)
122222861Smckusick 	{
122322861Smckusick 	s = BLANKCOMMON;
122422861Smckusick 	len = strlen(s);
122522861Smckusick 	}
122622861Smckusick p = mkext( varunder(len, s) );
122722861Smckusick if(p->extstg == STGUNKNOWN)
122822861Smckusick 	p->extstg = STGCOMMON;
122922861Smckusick else if(p->extstg != STGCOMMON)
123022861Smckusick 	{
123122861Smckusick 	errstr("%s cannot be a common block name", s);
123222861Smckusick 	return(0);
123322861Smckusick 	}
123422861Smckusick 
123522861Smckusick return( p );
123622861Smckusick }
123722861Smckusick 
123822861Smckusick 
123922861Smckusick incomm(c, v)
124022861Smckusick struct Extsym *c;
124122861Smckusick Namep v;
124222861Smckusick {
124322861Smckusick if(v->vstg != STGUNKNOWN)
124422861Smckusick 	dclerr("incompatible common declaration", v);
124522861Smckusick else
124622861Smckusick 	{
124722861Smckusick 	if(c == (struct Extsym *) 0)
124822861Smckusick 		return;		/* Illegal common block name upstream */
124922861Smckusick 	v->vstg = STGCOMMON;
125022861Smckusick 	c->extp = hookup(c->extp, mkchain(v,CHNULL) );
125122861Smckusick 	}
125222861Smckusick }
125322861Smckusick 
125422861Smckusick 
125522861Smckusick 
125622861Smckusick 
125722861Smckusick settype(v, type, length)
125822861Smckusick register Namep  v;
125922861Smckusick register int type;
126022861Smckusick register int length;
126122861Smckusick {
126222861Smckusick if(type == TYUNKNOWN)
126322861Smckusick 	return;
126422861Smckusick 
126522861Smckusick if(type==TYSUBR && v->vtype!=TYUNKNOWN && v->vstg==STGARG)
126622861Smckusick 	{
126722861Smckusick 	v->vtype = TYSUBR;
126822861Smckusick 	frexpr(v->vleng);
126922861Smckusick 	}
127022861Smckusick else if(type < 0)	/* storage class set */
127122861Smckusick 	{
127222861Smckusick 	if(v->vstg == STGUNKNOWN)
127322861Smckusick 		v->vstg = - type;
127422861Smckusick 	else if(v->vstg != -type)
127522861Smckusick 		dclerr("incompatible storage declarations", v);
127622861Smckusick 	}
127722861Smckusick else if(v->vtype == TYUNKNOWN)
127822861Smckusick 	{
127922861Smckusick 	if( (v->vtype = lengtype(type, length))==TYCHAR && length>=0)
128022861Smckusick 		v->vleng = ICON(length);
128122861Smckusick 	}
128222861Smckusick else if(v->vtype!=type || (type==TYCHAR && v->vleng->constblock.const.ci!=length) )
128322861Smckusick 	dclerr("incompatible type declarations", v);
128422861Smckusick }
128522861Smckusick 
128622861Smckusick 
128722861Smckusick 
128822861Smckusick 
128922861Smckusick 
129022861Smckusick lengtype(type, length)
129122861Smckusick register int type;
129222861Smckusick register int length;
129322861Smckusick {
129422861Smckusick switch(type)
129522861Smckusick 	{
129622861Smckusick 	case TYREAL:
129722861Smckusick 		if(length == 8)
129822861Smckusick 			return(TYDREAL);
129922861Smckusick 		if(length == 4)
130022861Smckusick 			goto ret;
130122861Smckusick 		break;
130222861Smckusick 
130322861Smckusick 	case TYCOMPLEX:
130422861Smckusick 		if(length == 16)
130522861Smckusick 			return(TYDCOMPLEX);
130622861Smckusick 		if(length == 8)
130722861Smckusick 			goto ret;
130822861Smckusick 		break;
130922861Smckusick 
131022861Smckusick 	case TYSHORT:
131122861Smckusick 	case TYDREAL:
131222861Smckusick 	case TYDCOMPLEX:
131322861Smckusick 	case TYCHAR:
131422861Smckusick 	case TYUNKNOWN:
131522861Smckusick 	case TYSUBR:
131622861Smckusick 	case TYERROR:
131722861Smckusick 		goto ret;
131822861Smckusick 
131922861Smckusick 	case TYLOGICAL:
132022861Smckusick 		if(length == typesize[TYLOGICAL])
132122861Smckusick 			goto ret;
132222861Smckusick 		break;
132322861Smckusick 
132422861Smckusick 	case TYLONG:
132522861Smckusick 		if(length == 0)
132622861Smckusick 			return(tyint);
132722861Smckusick 		if(length == 2)
132822861Smckusick 			return(TYSHORT);
132922861Smckusick 		if(length == 4)
133022861Smckusick 			goto ret;
133122861Smckusick 		break;
133222861Smckusick 	default:
133322861Smckusick 		badtype("lengtype", type);
133422861Smckusick 	}
133522861Smckusick 
133622861Smckusick if(length != 0)
133722861Smckusick 	err("incompatible type-length combination");
133822861Smckusick 
133922861Smckusick ret:
134022861Smckusick 	return(type);
134122861Smckusick }
134222861Smckusick 
134322861Smckusick 
134422861Smckusick 
134522861Smckusick 
134622861Smckusick 
134722861Smckusick setintr(v)
134822861Smckusick register Namep  v;
134922861Smckusick {
135022861Smckusick register int k;
135122861Smckusick 
135222861Smckusick if(v->vstg == STGUNKNOWN)
135322861Smckusick 	v->vstg = STGINTR;
135422861Smckusick else if(v->vstg!=STGINTR)
135522861Smckusick 	dclerr("incompatible use of intrinsic function", v);
135622861Smckusick if(v->vclass==CLUNKNOWN)
135722861Smckusick 	v->vclass = CLPROC;
135822861Smckusick if(v->vprocclass == PUNKNOWN)
135922861Smckusick 	v->vprocclass = PINTRINSIC;
136022861Smckusick else if(v->vprocclass != PINTRINSIC)
136122861Smckusick 	dclerr("invalid intrinsic declaration", v);
136222861Smckusick if(k = intrfunct(v->varname))
136322861Smckusick 	v->vardesc.varno = k;
136422861Smckusick else
136522861Smckusick 	dclerr("unknown intrinsic function", v);
136622861Smckusick }
136722861Smckusick 
136822861Smckusick 
136922861Smckusick 
137022861Smckusick setext(v)
137122861Smckusick register Namep  v;
137222861Smckusick {
137322861Smckusick if(v->vclass == CLUNKNOWN)
137422861Smckusick 	v->vclass = CLPROC;
137522861Smckusick else if(v->vclass != CLPROC)
137622861Smckusick 	dclerr("conflicting declarations", v);
137722861Smckusick 
137822861Smckusick if(v->vprocclass == PUNKNOWN)
137922861Smckusick 	v->vprocclass = PEXTERNAL;
138022861Smckusick else if(v->vprocclass != PEXTERNAL)
138122861Smckusick 	dclerr("conflicting declarations", v);
138222861Smckusick }
138322861Smckusick 
138422861Smckusick 
138522861Smckusick 
138622861Smckusick 
138722861Smckusick /* create dimensions block for array variable */
138822861Smckusick 
138922861Smckusick setbound(v, nd, dims)
139022861Smckusick register Namep  v;
139122861Smckusick int nd;
139222861Smckusick struct { expptr lb, ub; } dims[ ];
139322861Smckusick {
139422861Smckusick register expptr q, t;
139522861Smckusick register struct Dimblock *p;
139622861Smckusick int i;
139722861Smckusick 
139822861Smckusick if(v->vclass == CLUNKNOWN)
139922861Smckusick 	v->vclass = CLVAR;
140022861Smckusick else if(v->vclass != CLVAR)
140122861Smckusick 	{
140222861Smckusick 	dclerr("only variables may be arrays", v);
140322861Smckusick 	return;
140422861Smckusick 	}
140522861Smckusick if(v->vdim)
140622861Smckusick 	{
140722861Smckusick 	dclerr("redimensioned array", v);
140822861Smckusick 	return;
140922861Smckusick 	}
141022861Smckusick 
141122861Smckusick v->vdim = p = (struct Dimblock *)
141222861Smckusick 		ckalloc( sizeof(int) + (3+6*nd)*sizeof(expptr) );
141322861Smckusick p->ndim = nd;
141422861Smckusick p->nelt = ICON(1);
141522861Smckusick 
141622861Smckusick for(i=0 ; i<nd ; ++i)
141722861Smckusick 	{
141822861Smckusick #ifdef SDB
141922861Smckusick         if(sdbflag) {
142022861Smckusick /* Save the bounds trees built up by the grammar routines for use in stabs */
142122861Smckusick 
142222861Smckusick 		if(dims[i].lb == NULL) p->dims[i].lb=ICON(1);
142322861Smckusick         	else p->dims[i].lb= (expptr) cpexpr(dims[i].lb);
142422861Smckusick                 if(ISCONST(p->dims[i].lb)) p->dims[i].lbaddr = (expptr) PNULL;
142522861Smckusick                 else p->dims[i].lbaddr = (expptr) autovar(1, tyint, PNULL);
142622861Smckusick 
142722861Smckusick 		if(dims[i].ub == NULL) p->dims[i].ub=ICON(1);
142822861Smckusick         	else p->dims[i].ub = (expptr) cpexpr(dims[i].ub);
142922861Smckusick                 if(ISCONST(p->dims[i].ub)) p->dims[i].ubaddr = (expptr) PNULL;
143022861Smckusick                 else p->dims[i].ubaddr = (expptr) autovar(1, tyint, PNULL);
143122861Smckusick 	}
143222861Smckusick #endif
143322861Smckusick 	if( (q = dims[i].ub) == NULL)
143422861Smckusick 		{
143522861Smckusick 		if(i == nd-1)
143622861Smckusick 			{
143722861Smckusick 			frexpr(p->nelt);
143822861Smckusick 			p->nelt = NULL;
143922861Smckusick 			}
144022861Smckusick 		else
144122861Smckusick 			err("only last bound may be asterisk");
144222861Smckusick 		p->dims[i].dimsize = ICON(1);;
144322861Smckusick 		p->dims[i].dimexpr = NULL;
144422861Smckusick 		}
144522861Smckusick 	else
144622861Smckusick 		{
144722861Smckusick 		if(dims[i].lb)
144822861Smckusick 			{
144922861Smckusick 			q = mkexpr(OPMINUS, q, cpexpr(dims[i].lb));
145022861Smckusick 			q = mkexpr(OPPLUS, q, ICON(1) );
145122861Smckusick 			}
145222861Smckusick 		if( ISCONST(q) )
145322861Smckusick 			{
145422861Smckusick 			if (!ISINT(q->headblock.vtype)) {
145522861Smckusick 			   dclerr("dimension bounds must be integer expression", v);
145622861Smckusick 			   frexpr(q);
145722861Smckusick 			   q = ICON(0);
145822861Smckusick 			   }
145922861Smckusick 			if ( q->constblock.const.ci <= 0)
146022861Smckusick 			   {
146122861Smckusick 			   dclerr("array bounds out of sequence", v);
146222861Smckusick 			   frexpr(q);
146322861Smckusick 			   q = ICON(0);
146422861Smckusick 			   }
146522861Smckusick 			p->dims[i].dimsize = q;
146622861Smckusick 			p->dims[i].dimexpr = (expptr) PNULL;
146722861Smckusick 			}
146822861Smckusick 		else	{
146922861Smckusick 			p->dims[i].dimsize = (expptr) autovar(1, tyint, PNULL);
147022861Smckusick 			p->dims[i].dimexpr = q;
147122861Smckusick 			}
147222861Smckusick 		if(p->nelt)
147322861Smckusick 			p->nelt = mkexpr(OPSTAR, p->nelt,
147422861Smckusick 					cpexpr(p->dims[i].dimsize) );
147522861Smckusick 		}
147622861Smckusick 	}
147722861Smckusick 
147822861Smckusick q = dims[nd-1].lb;
147922861Smckusick if(q == NULL)
148022861Smckusick 	q = ICON(1);
148122861Smckusick 
148222861Smckusick for(i = nd-2 ; i>=0 ; --i)
148322861Smckusick 	{
148422861Smckusick 	t = dims[i].lb;
148522861Smckusick 	if(t == NULL)
148622861Smckusick 		t = ICON(1);
148722861Smckusick 	if(p->dims[i].dimsize)
148822861Smckusick 		q = mkexpr(OPPLUS, t, mkexpr(OPSTAR, cpexpr(p->dims[i].dimsize), q) );
148922861Smckusick 	}
149022861Smckusick 
149122861Smckusick if( ISCONST(q) )
149222861Smckusick 	{
149322861Smckusick 	p->baseoffset = q;
149422861Smckusick 	p->basexpr = NULL;
149522861Smckusick 	}
149622861Smckusick else
149722861Smckusick 	{
149822861Smckusick 	p->baseoffset = (expptr) autovar(1, tyint, PNULL);
149922861Smckusick 	p->basexpr = q;
150022861Smckusick 	}
150122861Smckusick }
150222861Smckusick 
150322861Smckusick 
150422861Smckusick 
150522861Smckusick /*
150622861Smckusick  * Check the dimensions of q to ensure that they are appropriately defined.
150722861Smckusick  */
150822861Smckusick LOCAL chkdim(q)
150922861Smckusick register Namep q;
151022861Smckusick {
151122861Smckusick   register struct Dimblock *p;
151222861Smckusick   register int i;
151322861Smckusick   expptr e;
151422861Smckusick 
151522861Smckusick   if (q == NULL)
151622861Smckusick     return;
151722861Smckusick   if (q->vclass != CLVAR)
151822861Smckusick     return;
151922861Smckusick   if (q->vdim == NULL)
152022861Smckusick     return;
152122861Smckusick   p = q->vdim;
152222861Smckusick   for (i = 0; i < p->ndim; ++i)
152322861Smckusick     {
152422861Smckusick #ifdef SDB
152522861Smckusick       if (sdbflag)
152622861Smckusick 	{
152722861Smckusick 	  if (e = p->dims[i].lb)
152822861Smckusick 	    chkdime(e, q);
152922861Smckusick 	  if (e = p->dims[i].ub)
153022861Smckusick 	    chkdime(e, q);
153122861Smckusick 	}
153222861Smckusick       else
153322861Smckusick #endif SDB
153422861Smckusick       if (e = p->dims[i].dimexpr)
153522861Smckusick 	chkdime(e, q);
153622861Smckusick     }
153722861Smckusick }
153822861Smckusick 
153922861Smckusick 
154022861Smckusick 
154122861Smckusick /*
154222861Smckusick  * The actual checking for chkdim() -- examines each expression.
154322861Smckusick  */
154422861Smckusick LOCAL chkdime(expr, q)
154522861Smckusick expptr expr;
154622861Smckusick Namep q;
154722861Smckusick {
154822861Smckusick   register expptr e;
154922861Smckusick 
155022861Smckusick   e = fixtype(cpexpr(expr));
155122861Smckusick   if (!ISINT(e->exprblock.vtype))
155222861Smckusick     dclerr("non-integer dimension", q);
155322861Smckusick   else if (!safedim(e))
155422861Smckusick     dclerr("undefined dimension", q);
155522861Smckusick   frexpr(e);
155622861Smckusick   return;
155722861Smckusick }
155822861Smckusick 
155922861Smckusick 
156022861Smckusick 
156122861Smckusick /*
156222861Smckusick  * A recursive routine to find undefined variables in dimension expressions.
156322861Smckusick  */
156422861Smckusick LOCAL safedim(e)
156522861Smckusick expptr e;
156622861Smckusick {
156722861Smckusick   chainp cp;
156822861Smckusick 
156922861Smckusick   if (e == NULL)
157022861Smckusick     return 1;
157122861Smckusick   switch (e->tag)
157222861Smckusick     {
157322861Smckusick       case TEXPR:
157422861Smckusick 	if (e->exprblock.opcode == OPCALL || e->exprblock.opcode == OPCCALL)
157522861Smckusick 	  return 0;
157622861Smckusick 	return safedim(e->exprblock.leftp) && safedim(e->exprblock.rightp);
157722861Smckusick       case TADDR:
157822861Smckusick 	switch (e->addrblock.vstg)
157922861Smckusick 	  {
158022861Smckusick 	    case STGCOMMON:
158122861Smckusick 	    case STGARG:
158222861Smckusick 	    case STGCONST:
158322861Smckusick 	    case STGEQUIV:
158422861Smckusick 	      if (e->addrblock.isarray)
158522861Smckusick 		return 0;
158622861Smckusick 	      return safedim(e->addrblock.memoffset);
158722861Smckusick 	    default:
158822861Smckusick 	      return 0;
158922861Smckusick 	  }
159022861Smckusick       case TCONST:
159122861Smckusick       case TTEMP:
159222861Smckusick 	return 1;
159322861Smckusick     }
159422861Smckusick   return 0;
159522861Smckusick }
159622861Smckusick 
159722861Smckusick 
159822861Smckusick 
159922861Smckusick LOCAL enlist(size, np, ep)
160022861Smckusick ftnint size;
160122861Smckusick Namep np;
160222861Smckusick struct Equivblock *ep;
160322861Smckusick {
160422861Smckusick   register sizelist *sp;
160522861Smckusick   register sizelist *t;
160622861Smckusick   register varlist *p;
160722861Smckusick 
160822861Smckusick   sp = varsizes;
160922861Smckusick 
161022861Smckusick   if (sp == NULL)
161122861Smckusick     {
161222861Smckusick       sp = ALLOC(SizeList);
161322861Smckusick       sp->size = size;
161422861Smckusick       varsizes = sp;
161522861Smckusick     }
161622861Smckusick   else
161722861Smckusick     {
161822861Smckusick       while (sp->size != size)
161922861Smckusick 	{
162022861Smckusick 	  if (sp->next != NULL && sp->next->size <= size)
162122861Smckusick 	    sp = sp->next;
162222861Smckusick 	  else
162322861Smckusick 	    {
162422861Smckusick 	      t = sp;
162522861Smckusick 	      sp = ALLOC(SizeList);
162622861Smckusick 	      sp->size = size;
162722861Smckusick 	      sp->next = t->next;
162822861Smckusick 	      t->next = sp;
162922861Smckusick 	    }
163022861Smckusick 	}
163122861Smckusick     }
163222861Smckusick 
163322861Smckusick   p = ALLOC(VarList);
163422861Smckusick   p->next = sp->vars;
163522861Smckusick   p->np = np;
163622861Smckusick   p->ep = ep;
163722861Smckusick 
163822861Smckusick   sp->vars = p;
163922861Smckusick 
164022861Smckusick   return;
164122861Smckusick }
164222861Smckusick 
164322861Smckusick 
164422861Smckusick 
164522861Smckusick outlocvars()
164622861Smckusick {
164722861Smckusick 
164822861Smckusick   register varlist *first, *last;
164922861Smckusick   register varlist *vp, *t;
165022861Smckusick   register sizelist *sp, *sp1;
165122861Smckusick   register Namep np;
165222861Smckusick   register struct Equivblock *ep;
165322861Smckusick   register int i;
165422861Smckusick   register int alt;
165522861Smckusick   register int type;
165622861Smckusick   char sname[100];
165722861Smckusick   char setbuff[100];
165822861Smckusick 
165922861Smckusick   sp = varsizes;
166022861Smckusick   if (sp == NULL)
166122861Smckusick     return;
166222861Smckusick 
166322861Smckusick   vp = sp->vars;
166422861Smckusick   if (vp->np != NULL)
166522861Smckusick     {
166622861Smckusick       np = vp->np;
166722861Smckusick       sprintf(setbuff, "\t.set\tv.%d,v.%d\n", bsslabel,
166822861Smckusick 	      np->vardesc.varno);
166922861Smckusick     }
167022861Smckusick   else
167122861Smckusick     {
167222861Smckusick       i = vp->ep - eqvclass;
167322861Smckusick       sprintf(setbuff, "\t.set\tv.%d,q.%d\n", bsslabel, i + eqvstart);
167422861Smckusick     }
167522861Smckusick 
167622861Smckusick   first = last = NULL;
167722861Smckusick   alt = NO;
167822861Smckusick 
167922861Smckusick   while (sp != NULL)
168022861Smckusick     {
168122861Smckusick       vp = sp->vars;
168222861Smckusick       while (vp != NULL)
168322861Smckusick 	{
168422861Smckusick 	  t = vp->next;
168522861Smckusick 	  if (alt == YES)
168622861Smckusick 	    {
168722861Smckusick 	      alt = NO;
168822861Smckusick 	      vp->next = first;
168922861Smckusick 	      first = vp;
169022861Smckusick 	    }
169122861Smckusick 	  else
169222861Smckusick 	    {
169322861Smckusick 	      alt = YES;
169422861Smckusick 	      if (last != NULL)
169522861Smckusick 	        last->next = vp;
169622861Smckusick 	      else
169722861Smckusick 		first = vp;
169822861Smckusick 	      vp->next = NULL;
169922861Smckusick 	      last = vp;
170022861Smckusick 	    }
170122861Smckusick 	  vp = t;
170222861Smckusick 	}
170322861Smckusick       sp1 = sp;
170422861Smckusick       sp = sp->next;
170522861Smckusick       free((char *) sp1);
170622861Smckusick     }
170722861Smckusick 
170822861Smckusick   vp = first;
170922861Smckusick   while(vp != NULL)
171022861Smckusick     {
171122861Smckusick       if (vp->np != NULL)
171222861Smckusick 	{
171322861Smckusick 	  np = vp->np;
171422861Smckusick 	  sprintf(sname, "v.%d", np->vardesc.varno);
171522861Smckusick 	  if (np->init)
171622861Smckusick 	    prlocdata(sname, np->varsize, np->vtype, np->initoffset,
171722861Smckusick 		      &(np->inlcomm));
171822861Smckusick 	  else
171922861Smckusick 	    {
172022861Smckusick 	      pralign(typealign[np->vtype]);
172122861Smckusick 	      fprintf(initfile, "%s:\n\t.space\t%d\n", sname,
172222861Smckusick 		      np->varsize);
172322861Smckusick 	    }
172422861Smckusick 	  np->inlcomm = NO;
172522861Smckusick 	}
172622861Smckusick       else
172722861Smckusick 	{
172822861Smckusick 	  ep = vp->ep;
172922861Smckusick 	  i = ep - eqvclass;
173022861Smckusick 	  if (ep->eqvleng >= 8)
173122861Smckusick 	    type = TYDREAL;
173222861Smckusick 	  else if (ep->eqvleng >= 4)
173322861Smckusick 	    type = TYLONG;
173422861Smckusick 	  else if (ep->eqvleng >= 2)
173522861Smckusick 	    type = TYSHORT;
173622861Smckusick 	  else
173722861Smckusick 	    type = TYCHAR;
173822861Smckusick 	  sprintf(sname, "q.%d", i + eqvstart);
173922861Smckusick 	  if (ep->init)
174022861Smckusick 	    prlocdata(sname, ep->eqvleng, type, ep->initoffset,
174122861Smckusick 		      &(ep->inlcomm));
174222861Smckusick 	  else
174322861Smckusick 	    {
174422861Smckusick 	      pralign(typealign[type]);
174522861Smckusick 	      fprintf(initfile, "%s:\n\t.space\t%d\n", sname, ep->eqvleng);
174622861Smckusick 	    }
174722861Smckusick 	  ep->inlcomm = NO;
174822861Smckusick 	}
174922861Smckusick       t = vp;
175022861Smckusick       vp = vp->next;
175122861Smckusick       free((char *) t);
175222861Smckusick     }
175322861Smckusick   fprintf(initfile, "%s\n", setbuff);
175422861Smckusick   return;
175522861Smckusick }
1756