xref: /csrg-svn/usr.bin/f77/pass1.tahoe/proc.c (revision 46305)
143220Sbostic /*
243220Sbostic  * Copyright (c) 1980 Regents of the University of California.
343220Sbostic  * All rights reserved.  The Berkeley software License Agreement
443220Sbostic  * specifies the terms and conditions for redistribution.
543220Sbostic  */
643220Sbostic 
743220Sbostic #ifndef lint
843220Sbostic static char sccsid[] = "@(#)proc.c	5.2 (Berkeley) 6/9/85";
943220Sbostic #endif not lint
1043220Sbostic 
1143220Sbostic /*
1243220Sbostic  * proc.c
1343220Sbostic  *
1443220Sbostic  * Routines for handling procedures, f77 compiler, pass 1.
1543220Sbostic  *
1643220Sbostic  * University of Utah CS Dept modification history:
1743220Sbostic  *
1843220Sbostic  * $Header: proc.c,v 3.11 85/06/04 03:45:29 donn Exp $
1943220Sbostic  * $Log:	proc.c,v $
2043220Sbostic  * Revision 3.11  85/06/04  03:45:29  donn
2143220Sbostic  * Changed retval() to recognize that a function declaration might have
2243220Sbostic  * bombed out earlier, leaving an error node behind...
2343220Sbostic  *
2443220Sbostic  * Revision 3.10  85/03/08  23:13:06  donn
2543220Sbostic  * Finally figured out why function calls and array elements are not legal
2643220Sbostic  * dummy array dimension declarator elements.  Hacked safedim() to stop 'em.
2743220Sbostic  *
2843220Sbostic  * Revision 3.9  85/02/02  00:26:10  donn
2943220Sbostic  * Removed the call to entrystab() in enddcl() -- this was redundant (it was
3043220Sbostic  * also done in startproc()) and confusing to dbx to boot.
3143220Sbostic  *
3243220Sbostic  * Revision 3.8  85/01/14  04:21:53  donn
3343220Sbostic  * Added changes to implement Jerry's '-q' option.
3443220Sbostic  *
3543220Sbostic  * Revision 3.7  85/01/11  21:10:35  donn
3643220Sbostic  * In conjunction with other changes to implement SAVE statements, function
3743220Sbostic  * nameblocks were changed to make it appear that they are 'saved' too --
3843220Sbostic  * this arranges things so that function return values are forced out of
3943220Sbostic  * register before a return.
4043220Sbostic  *
4143220Sbostic  * Revision 3.6  84/12/10  19:27:20  donn
4243220Sbostic  * comblock() signals an illegal common block name by returning a null pointer,
4343220Sbostic  * but incomm() wasn't able to handle it, leading to core dumps.  I put the
4443220Sbostic  * fix in incomm() to pick up null common blocks.
4543220Sbostic  *
4643220Sbostic  * Revision 3.5  84/11/21  20:33:31  donn
4743220Sbostic  * It seems that I/O elements are treated as character strings so that their
4843220Sbostic  * length can be passed to the I/O routines...  Unfortunately the compiler
4943220Sbostic  * assumes that no temporaries can be of type CHARACTER and casually tosses
5043220Sbostic  * length and type info away when removing TEMP blocks.  This has been fixed...
5143220Sbostic  *
5243220Sbostic  * Revision 3.4  84/11/05  22:19:30  donn
5343220Sbostic  * Fixed a silly bug in the last fix.
5443220Sbostic  *
5543220Sbostic  * Revision 3.3  84/10/29  08:15:23  donn
5643220Sbostic  * Added code to check the type and shape of subscript declarations,
5743220Sbostic  * per Jerry Berkman's suggestion.
5843220Sbostic  *
5943220Sbostic  * Revision 3.2  84/10/29  05:52:07  donn
6043220Sbostic  * Added change suggested by Jerry Berkman to report an error when an array
6143220Sbostic  * is redimensioned.
6243220Sbostic  *
6343220Sbostic  * Revision 3.1  84/10/13  02:12:31  donn
6443220Sbostic  * Merged Jerry Berkman's version into mine.
6543220Sbostic  *
6643220Sbostic  * Revision 2.1  84/07/19  12:04:09  donn
6743220Sbostic  * Changed comment headers for UofU.
6843220Sbostic  *
6943220Sbostic  * Revision 1.6  84/07/19  11:32:15  donn
7043220Sbostic  * Incorporated fix to setbound() to detect backward array subscript limits.
7143220Sbostic  * The fix is by Bob Corbett, donated by Jerry Berkman.
7243220Sbostic  *
7343220Sbostic  * Revision 1.5  84/07/18  18:25:50  donn
7443220Sbostic  * Fixed problem with doentry() where a placeholder for a return value
7543220Sbostic  * was not allocated if the first entry didn't require one but a later
7643220Sbostic  * entry did.
7743220Sbostic  *
7843220Sbostic  * Revision 1.4  84/05/24  20:52:09  donn
7943220Sbostic  * Installed firewall #ifdef around the code that recycles stack temporaries,
8043220Sbostic  * since it seems to be broken and lacks a good fix for the time being.
8143220Sbostic  *
8243220Sbostic  * Revision 1.3  84/04/16  09:50:46  donn
8343220Sbostic  * Fixed mkargtemp() so that it only passes back a copy of a temporary, keeping
8443220Sbostic  * the original for its own use.  This fixes a set of bugs that are caused by
8543220Sbostic  * elements in the argtemplist getting stomped on.
8643220Sbostic  *
8743220Sbostic  * Revision 1.2  84/02/28  21:12:58  donn
8843220Sbostic  * Added Berkeley changes for subroutine call argument temporaries fix.
8943220Sbostic  *
9043220Sbostic  */
9143220Sbostic 
9243220Sbostic #include "defs.h"
9343220Sbostic 
9443220Sbostic #ifdef SDB
9543220Sbostic #	include <a.out.h>
9643220Sbostic #	ifndef N_SO
9743220Sbostic #		include <stab.h>
9843220Sbostic #	endif
9943220Sbostic #endif
10043220Sbostic 
10143220Sbostic extern flag namesflag;
10243220Sbostic 
10343220Sbostic typedef
10443220Sbostic   struct SizeList
10543220Sbostic     {
10643220Sbostic       struct SizeList *next;
10743220Sbostic       ftnint size;
10843220Sbostic       struct VarList *vars;
10943220Sbostic     }
11043220Sbostic   sizelist;
11143220Sbostic 
11243220Sbostic 
11343220Sbostic typedef
11443220Sbostic   struct VarList
11543220Sbostic     {
11643220Sbostic       struct VarList *next;
11743220Sbostic       Namep np;
11843220Sbostic       struct Equivblock *ep;
11943220Sbostic     }
12043220Sbostic   varlist;
12143220Sbostic 
12243220Sbostic 
12343220Sbostic LOCAL sizelist *varsizes;
12443220Sbostic 
12543220Sbostic 
12643220Sbostic /* start a new procedure */
12743220Sbostic 
12843220Sbostic newproc()
12943220Sbostic {
13043220Sbostic if(parstate != OUTSIDE)
13143220Sbostic 	{
13243220Sbostic 	execerr("missing end statement", CNULL);
13343220Sbostic 	endproc();
13443220Sbostic 	}
13543220Sbostic 
13643220Sbostic parstate = INSIDE;
13743220Sbostic procclass = CLMAIN;	/* default */
13843220Sbostic }
13943220Sbostic 
14043220Sbostic 
14143220Sbostic 
14243220Sbostic /* end of procedure. generate variables, epilogs, and prologs */
14343220Sbostic 
14443220Sbostic endproc()
14543220Sbostic {
14643220Sbostic struct Labelblock *lp;
14743220Sbostic 
14843220Sbostic if(parstate < INDATA)
14943220Sbostic 	enddcl();
15043220Sbostic if(ctlstack >= ctls)
15143220Sbostic 	err("DO loop or BLOCK IF not closed");
15243220Sbostic for(lp = labeltab ; lp < labtabend ; ++lp)
15343220Sbostic 	if(lp->stateno!=0 && lp->labdefined==NO)
15443220Sbostic 		errstr("missing statement number %s", convic(lp->stateno) );
15543220Sbostic 
15643220Sbostic if (optimflag)
15743220Sbostic   optimize();
15843220Sbostic 
15943220Sbostic outiodata();
16043220Sbostic epicode();
16143220Sbostic procode();
16243220Sbostic donmlist();
16343220Sbostic dobss();
16443220Sbostic 
16543220Sbostic #if FAMILY == PCC
16643220Sbostic 	putbracket();
16743220Sbostic #endif
16843220Sbostic procinit();	/* clean up for next procedure */
16943220Sbostic }
17043220Sbostic 
17143220Sbostic 
17243220Sbostic 
17343220Sbostic /* End of declaration section of procedure.  Allocate storage. */
17443220Sbostic 
17543220Sbostic enddcl()
17643220Sbostic {
17743220Sbostic register struct Entrypoint *ep;
17843220Sbostic 
17943220Sbostic parstate = INEXEC;
18043220Sbostic docommon();
18143220Sbostic doequiv();
18243220Sbostic docomleng();
18343220Sbostic for(ep = entries ; ep ; ep = ep->entnextp) {
18443220Sbostic 	doentry(ep);
18543220Sbostic }
18643220Sbostic }
18743220Sbostic 
18843220Sbostic /* ROUTINES CALLED WHEN ENCOUNTERING ENTRY POINTS */
18943220Sbostic 
19043220Sbostic /* Main program or Block data */
19143220Sbostic 
19243220Sbostic startproc(prgname, class)
19343220Sbostic Namep prgname;
19443220Sbostic int class;
19543220Sbostic {
19643220Sbostic struct Extsym *progname;
19743220Sbostic register struct Entrypoint *p;
19843220Sbostic 
19943220Sbostic if(prgname)
20043220Sbostic 	procname = prgname->varname;
20143220Sbostic if(namesflag == YES) {
20243220Sbostic 	fprintf(diagfile, "   %s", (class==CLMAIN ? "MAIN" : "BLOCK DATA") );
20343220Sbostic 	if(prgname)
20443220Sbostic 		fprintf(diagfile, " %s", varstr(XL, procname) );
20543220Sbostic 	fprintf(diagfile, ":\n");
20643220Sbostic 	}
20743220Sbostic 
20843220Sbostic if( prgname )
20943220Sbostic 	progname = newentry( prgname );
21043220Sbostic else
21143220Sbostic 	progname = NULL;
21243220Sbostic 
21343220Sbostic p = ALLOC(Entrypoint);
21443220Sbostic if(class == CLMAIN)
21543220Sbostic 	puthead("MAIN_", CLMAIN);
21643220Sbostic else
21743220Sbostic 	puthead(CNULL, CLBLOCK);
21843220Sbostic if(class == CLMAIN)
21943220Sbostic 	newentry( mkname(5, "MAIN") );
22043220Sbostic p->entryname = progname;
22143220Sbostic p->entrylabel = newlabel();
22243220Sbostic entries = p;
22343220Sbostic 
22443220Sbostic procclass = class;
22543220Sbostic retlabel = newlabel();
22643220Sbostic #ifdef SDB
22743220Sbostic if(sdbflag) {
22843220Sbostic          entrystab(p,class);
22943220Sbostic }
23043220Sbostic #endif
23143220Sbostic }
23243220Sbostic 
23343220Sbostic /* subroutine or function statement */
23443220Sbostic 
23543220Sbostic struct Extsym *newentry(v)
23643220Sbostic register Namep v;
23743220Sbostic {
23843220Sbostic register struct Extsym *p;
23943220Sbostic 
24043220Sbostic p = mkext( varunder(VL, v->varname) );
24143220Sbostic 
24243220Sbostic if(p==NULL || p->extinit || ! ONEOF(p->extstg, M(STGUNKNOWN)|M(STGEXT)) )
24343220Sbostic 	{
24443220Sbostic 	if(p == 0)
24543220Sbostic 		dclerr("invalid entry name", v);
24643220Sbostic 	else	dclerr("external name already used", v);
24743220Sbostic 	return(0);
24843220Sbostic 	}
24943220Sbostic v->vstg = STGAUTO;
25043220Sbostic v->vprocclass = PTHISPROC;
25143220Sbostic v->vclass = CLPROC;
25243220Sbostic p->extstg = STGEXT;
25343220Sbostic p->extinit = YES;
25443220Sbostic return(p);
25543220Sbostic }
25643220Sbostic 
25743220Sbostic 
25843220Sbostic entrypt(class, type, length, entname, args)
25943220Sbostic int class, type;
26043220Sbostic ftnint length;
26143220Sbostic Namep entname;
26243220Sbostic chainp args;
26343220Sbostic {
26443220Sbostic struct Extsym *entry;
26543220Sbostic register Namep q;
26643220Sbostic register struct Entrypoint *p, *ep;
26743220Sbostic 
26843220Sbostic if(namesflag == YES) {
26943220Sbostic 	if(class == CLENTRY)
27043220Sbostic 		fprintf(diagfile, "       entry ");
27143220Sbostic 	if(entname)
27243220Sbostic 		fprintf(diagfile, "   %s", varstr(XL, entname->varname) );
27343220Sbostic 	fprintf(diagfile, ":\n");
27443220Sbostic 	}
27543220Sbostic 
27643220Sbostic if( entname->vclass == CLPARAM ) {
27743220Sbostic 	errstr("entry name %s used in 'parameter' statement",
27843220Sbostic 		varstr(XL, entname->varname) );
27943220Sbostic 	return;
28043220Sbostic 	}
28143220Sbostic if( ((type == TYSUBR) || (class == CLENTRY && proctype == TYSUBR))
28243220Sbostic 	&& (entname->vtype != TYUNKNOWN && entname->vtype != TYSUBR) ) {
28343220Sbostic 	errstr("subroutine entry %s previously declared",
28443220Sbostic 		varstr(XL, entname->varname) );
28543220Sbostic 	return;
28643220Sbostic 	}
28743220Sbostic if(  (entname->vstg != STGEXT && entname->vstg != STGUNKNOWN)
28843220Sbostic 	||  (entname->vdim != NULL) ) {
28943220Sbostic 	errstr("subroutine or function entry %s previously declared",
29043220Sbostic 		varstr(XL, entname->varname) );
29143220Sbostic 	return;
29243220Sbostic 	}
29343220Sbostic 
29443220Sbostic if( (class == CLPROC || class == CLENTRY) && type != TYSUBR )
29543220Sbostic 	/* arrange to save function return values */
29643220Sbostic 	entname->vsave = YES;
29743220Sbostic 
29843220Sbostic entry = newentry( entname );
29943220Sbostic 
30043220Sbostic if(class != CLENTRY)
30143220Sbostic 	puthead( varstr(XL, procname = entry->extname), class);
30243220Sbostic q = mkname(VL, nounder(XL,entry->extname) );
30343220Sbostic 
30443220Sbostic if( (type = lengtype(type, (int) length)) != TYCHAR)
30543220Sbostic 	length = 0;
30643220Sbostic if(class == CLPROC)
30743220Sbostic 	{
30843220Sbostic 	procclass = CLPROC;
30943220Sbostic 	proctype = type;
31043220Sbostic 	procleng = length;
31143220Sbostic 
31243220Sbostic 	retlabel = newlabel();
31343220Sbostic 	if(type == TYSUBR)
31443220Sbostic 		ret0label = newlabel();
31543220Sbostic 	}
31643220Sbostic 
31743220Sbostic p = ALLOC(Entrypoint);
31843220Sbostic if(entries)	/* put new block at end of entries list */
31943220Sbostic 	{
32043220Sbostic 	for(ep = entries; ep->entnextp; ep = ep->entnextp)
32143220Sbostic 		;
32243220Sbostic 	ep->entnextp = p;
32343220Sbostic 	}
32443220Sbostic else
32543220Sbostic 	entries = p;
32643220Sbostic 
32743220Sbostic p->entryname = entry;
32843220Sbostic p->arglist = args;
32943220Sbostic p->entrylabel = newlabel();
33043220Sbostic p->enamep = q;
33143220Sbostic 
33243220Sbostic if(class == CLENTRY)
33343220Sbostic 	{
33443220Sbostic 	class = CLPROC;
33543220Sbostic 	if(proctype == TYSUBR)
33643220Sbostic 		type = TYSUBR;
33743220Sbostic 	}
33843220Sbostic 
33943220Sbostic q->vclass = class;
34043220Sbostic q->vprocclass = PTHISPROC;
34143220Sbostic settype(q, type, (int) length);
34243220Sbostic /* hold all initial entry points till end of declarations */
34343220Sbostic if(parstate >= INDATA) {
34443220Sbostic 	doentry(p);
34543220Sbostic }
34643220Sbostic #ifdef SDB
34743220Sbostic 	if(sdbflag)
34843220Sbostic 	{ /* may need to preserve CLENTRY here */
34943220Sbostic 	entrystab(p,class);
35043220Sbostic 	}
35143220Sbostic #endif
35243220Sbostic }
35343220Sbostic 
35443220Sbostic /* generate epilogs */
35543220Sbostic 
35643220Sbostic LOCAL epicode()
35743220Sbostic {
35843220Sbostic register int i;
35943220Sbostic 
36043220Sbostic if(procclass==CLPROC)
36143220Sbostic 	{
36243220Sbostic 	if(proctype==TYSUBR)
36343220Sbostic 		{
36443220Sbostic 		putlabel(ret0label);
36543220Sbostic 		if(substars)
36643220Sbostic 			putforce(TYINT, ICON(0) );
36743220Sbostic 		putlabel(retlabel);
36843220Sbostic 		goret(TYSUBR);
36943220Sbostic 		}
37043220Sbostic 	else	{
37143220Sbostic 		putlabel(retlabel);
37243220Sbostic 		if(multitype)
37343220Sbostic 			{
37443220Sbostic 			typeaddr = autovar(1, TYADDR, PNULL);
37543220Sbostic 			putbranch( cpexpr(typeaddr) );
37643220Sbostic 			for(i = 0; i < NTYPES ; ++i)
37743220Sbostic 				if(rtvlabel[i] != 0)
37843220Sbostic 					{
37943220Sbostic 					putlabel(rtvlabel[i]);
38043220Sbostic 					retval(i);
38143220Sbostic 					}
38243220Sbostic 			}
38343220Sbostic 		else
38443220Sbostic 			retval(proctype);
38543220Sbostic 		}
38643220Sbostic 	}
38743220Sbostic 
38843220Sbostic else if(procclass != CLBLOCK)
38943220Sbostic 	{
39043220Sbostic 	putlabel(retlabel);
39143220Sbostic 	goret(TYSUBR);
39243220Sbostic 	}
39343220Sbostic }
39443220Sbostic 
39543220Sbostic 
39643220Sbostic /* generate code to return value of type  t */
39743220Sbostic 
39843220Sbostic LOCAL retval(t)
39943220Sbostic register int t;
40043220Sbostic {
40143220Sbostic register Addrp p;
40243220Sbostic 
40343220Sbostic switch(t)
40443220Sbostic 	{
40543220Sbostic 	case TYCHAR:
40643220Sbostic 	case TYCOMPLEX:
40743220Sbostic 	case TYDCOMPLEX:
40843220Sbostic 		break;
40943220Sbostic 
41043220Sbostic 	case TYLOGICAL:
41143220Sbostic 		t = tylogical;
41243220Sbostic 	case TYADDR:
41343220Sbostic 	case TYSHORT:
41443220Sbostic 	case TYLONG:
41543220Sbostic 		p = (Addrp) cpexpr(retslot);
41643220Sbostic 		p->vtype = t;
41743220Sbostic 		putforce(t, p);
41843220Sbostic 		break;
41943220Sbostic 
42043220Sbostic 	case TYREAL:
42143220Sbostic 	case TYDREAL:
42243220Sbostic 		p = (Addrp) cpexpr(retslot);
42343220Sbostic 		p->vtype = t;
42443220Sbostic 		putforce(t, p);
42543220Sbostic 		break;
42643220Sbostic 
42743220Sbostic 	case TYERROR:
42843220Sbostic 		return;		/* someone else already complained */
42943220Sbostic 
43043220Sbostic 	default:
43143220Sbostic 		badtype("retval", t);
43243220Sbostic 	}
43343220Sbostic goret(t);
43443220Sbostic }
43543220Sbostic 
43643220Sbostic 
43743220Sbostic /* Allocate extra argument array if needed. Generate prologs. */
43843220Sbostic 
43943220Sbostic LOCAL procode()
44043220Sbostic {
44143220Sbostic register struct Entrypoint *p;
44243220Sbostic Addrp argvec;
44343220Sbostic 
44443220Sbostic #if TARGET==GCOS
44543220Sbostic 	argvec = autovar(lastargslot/SZADDR, TYADDR, PNULL);
44643220Sbostic #else
44743220Sbostic 	if(lastargslot>0 && nentry>1)
44843220Sbostic #if TARGET == VAX || TARGET == TAHOE
44943220Sbostic 		argvec = autovar(1 + lastargslot/SZADDR, TYADDR, PNULL);
45043220Sbostic #else
45143220Sbostic 		argvec = autovar(lastargslot/SZADDR, TYADDR, PNULL);
45243220Sbostic #endif
45343220Sbostic 	else
45443220Sbostic 		argvec = NULL;
45543220Sbostic #endif
45643220Sbostic 
45743220Sbostic 
45843220Sbostic #if TARGET == PDP11
45943220Sbostic 	/* for the optimizer */
46043220Sbostic 	if(fudgelabel)
46143220Sbostic 		putlabel(fudgelabel);
46243220Sbostic #endif
46343220Sbostic 
46443220Sbostic for(p = entries ; p ; p = p->entnextp)
46543220Sbostic 	prolog(p, argvec);
46643220Sbostic 
46743220Sbostic #if FAMILY == PCC
46843220Sbostic 	putrbrack(procno);
46943220Sbostic #endif
47043220Sbostic 
47143220Sbostic prendproc();
47243220Sbostic }
47343220Sbostic 
47443220Sbostic 
47543220Sbostic /*
47643220Sbostic    manipulate argument lists (allocate argument slot positions)
47743220Sbostic  * keep track of return types and labels
47843220Sbostic  */
47943220Sbostic 
48043220Sbostic LOCAL doentry(ep)
48143220Sbostic struct Entrypoint *ep;
48243220Sbostic {
48343220Sbostic register int type;
48443220Sbostic register Namep np;
48543220Sbostic chainp p;
48643220Sbostic register Namep q;
48743220Sbostic Addrp mkarg();
48843220Sbostic 
48943220Sbostic ++nentry;
49043220Sbostic if(procclass == CLMAIN)
49143220Sbostic 	{
49243220Sbostic 	if (optimflag)
49343220Sbostic 		optbuff (SKLABEL, 0, ep->entrylabel, 0);
49443220Sbostic 	else
49543220Sbostic 		putlabel(ep->entrylabel);
49643220Sbostic 	return;
49743220Sbostic 	}
49843220Sbostic else if(procclass == CLBLOCK)
49943220Sbostic 	return;
50043220Sbostic 
50143220Sbostic impldcl( np = mkname(VL, nounder(XL, ep->entryname->extname) ) );
50243220Sbostic type = np->vtype;
50343220Sbostic if(proctype == TYUNKNOWN)
50443220Sbostic 	if( (proctype = type) == TYCHAR)
505*46305Sbostic 		procleng = (np->vleng ? np->vleng->constblock.constant.ci : (ftnint) (-1));
50643220Sbostic 
50743220Sbostic if(proctype == TYCHAR)
50843220Sbostic 	{
50943220Sbostic 	if(type != TYCHAR)
51043220Sbostic 		err("noncharacter entry of character function");
511*46305Sbostic 	else if( (np->vleng ? np->vleng->constblock.constant.ci : (ftnint) (-1)) != procleng)
51243220Sbostic 		err("mismatched character entry lengths");
51343220Sbostic 	}
51443220Sbostic else if(type == TYCHAR)
51543220Sbostic 	err("character entry of noncharacter function");
51643220Sbostic else if(type != proctype)
51743220Sbostic 	multitype = YES;
51843220Sbostic if(rtvlabel[type] == 0)
51943220Sbostic 	rtvlabel[type] = newlabel();
52043220Sbostic ep->typelabel = rtvlabel[type];
52143220Sbostic 
52243220Sbostic if(type == TYCHAR)
52343220Sbostic 	{
52443220Sbostic 	if(chslot < 0)
52543220Sbostic 		{
52643220Sbostic 		chslot = nextarg(TYADDR);
52743220Sbostic 		chlgslot = nextarg(TYLENG);
52843220Sbostic 		}
52943220Sbostic 	np->vstg = STGARG;
53043220Sbostic 	np->vardesc.varno = chslot;
53143220Sbostic 	if(procleng < 0)
53243220Sbostic 		np->vleng = (expptr) mkarg(TYLENG, chlgslot);
53343220Sbostic 	}
53443220Sbostic else if( ISCOMPLEX(type) )
53543220Sbostic 	{
53643220Sbostic 	np->vstg = STGARG;
53743220Sbostic 	if(cxslot < 0)
53843220Sbostic 		cxslot = nextarg(TYADDR);
53943220Sbostic 	np->vardesc.varno = cxslot;
54043220Sbostic 	}
54143220Sbostic else if(type != TYSUBR)
54243220Sbostic 	{
54343220Sbostic 	if(retslot == NULL)
54443220Sbostic 		retslot = autovar(1, TYDREAL, PNULL);
54543220Sbostic 	np->vstg = STGAUTO;
546*46305Sbostic 	np->voffset = retslot->memoffset->constblock.constant.ci;
54743220Sbostic 	}
54843220Sbostic 
54943220Sbostic for(p = ep->arglist ; p ; p = p->nextp)
55043220Sbostic 	if(! (( q = (Namep) (p->datap) )->vdcldone) )
55143220Sbostic 		q->vardesc.varno = nextarg(TYADDR);
55243220Sbostic 
55343220Sbostic for(p = ep->arglist ; p ; p = p->nextp)
55443220Sbostic 	if(! (( q = (Namep) (p->datap) )->vdcldone) )
55543220Sbostic 		{
55643220Sbostic 		impldcl(q);
55743220Sbostic 		q->vdcldone = YES;
55843220Sbostic 		if(q->vtype == TYCHAR)
55943220Sbostic 			{
56043220Sbostic 			if(q->vleng == NULL)	/* character*(*) */
56143220Sbostic 				q->vleng = (expptr)
56243220Sbostic 						mkarg(TYLENG, nextarg(TYLENG) );
56343220Sbostic 			else if(nentry == 1)
56443220Sbostic 				nextarg(TYLENG);
56543220Sbostic 			}
56643220Sbostic 		else if(q->vclass==CLPROC && nentry==1)
56743220Sbostic 			nextarg(TYLENG) ;
56843220Sbostic #ifdef SDB
56943220Sbostic 		if(sdbflag) {
57043220Sbostic 			namestab(q);
57143220Sbostic 		}
57243220Sbostic #endif
57343220Sbostic 		}
57443220Sbostic 
57543220Sbostic if (optimflag)
57643220Sbostic 	optbuff (SKLABEL, 0, ep->entrylabel, 0);
57743220Sbostic else
57843220Sbostic 	putlabel(ep->entrylabel);
57943220Sbostic }
58043220Sbostic 
58143220Sbostic 
58243220Sbostic 
58343220Sbostic LOCAL nextarg(type)
58443220Sbostic int type;
58543220Sbostic {
58643220Sbostic int k;
58743220Sbostic k = lastargslot;
58843220Sbostic lastargslot += typesize[type];
58943220Sbostic return(k);
59043220Sbostic }
59143220Sbostic 
59243220Sbostic /* generate variable references */
59343220Sbostic 
59443220Sbostic LOCAL dobss()
59543220Sbostic {
59643220Sbostic register struct Hashentry *p;
59743220Sbostic register Namep q;
59843220Sbostic register int i;
59943220Sbostic int align;
60043220Sbostic ftnint leng, iarrl;
60143220Sbostic char *memname();
60243220Sbostic int qstg, qclass, qtype;
60343220Sbostic 
60443220Sbostic pruse(asmfile, USEBSS);
60543220Sbostic varsizes = NULL;
60643220Sbostic 
60743220Sbostic for(p = hashtab ; p<lasthash ; ++p)
60843220Sbostic     if(q = p->varp)
60943220Sbostic 	{
61043220Sbostic 	qstg = q->vstg;
61143220Sbostic 	qtype = q->vtype;
61243220Sbostic 	qclass = q->vclass;
61343220Sbostic 
61443220Sbostic 	if( (qclass==CLUNKNOWN && qstg!=STGARG) ||
61543220Sbostic 	    (qclass==CLVAR && qstg==STGUNKNOWN) )
61643220Sbostic 		warn1("local variable %s never used", varstr(VL,q->varname) );
61743220Sbostic 	else if(qclass==CLPROC && q->vprocclass==PEXTERNAL && qstg!=STGARG)
61843220Sbostic 		mkext(varunder(VL, q->varname)) ->extstg = STGEXT;
61943220Sbostic 
62043220Sbostic 	if (qclass == CLVAR && qstg == STGBSS)
62143220Sbostic 	  {
62243220Sbostic 	    if (SMALLVAR(q->varsize))
62343220Sbostic 	      {
62443220Sbostic 		enlist(q->varsize, q, NULL);
62543220Sbostic 		q->inlcomm = NO;
62643220Sbostic 	      }
62743220Sbostic 	    else
62843220Sbostic 	      {
62943220Sbostic 		if (q->init == NO)
63043220Sbostic 		  {
63143220Sbostic 		    preven(ALIDOUBLE);
63243220Sbostic 		    prlocvar(memname(qstg, q->vardesc.varno), q->varsize);
63343220Sbostic 		    q->inlcomm = YES;
63443220Sbostic 		  }
63543220Sbostic 		else
63643220Sbostic 		  prlocdata(memname(qstg, q->vardesc.varno), q->varsize,
63743220Sbostic 			    q->vtype, q->initoffset, &(q->inlcomm));
63843220Sbostic 	      }
63943220Sbostic 	  }
64043220Sbostic 	else if(qclass==CLVAR && qstg!=STGARG)
64143220Sbostic 		{
64243220Sbostic 		if(q->vdim && !ISICON(q->vdim->nelt) )
64343220Sbostic 			dclerr("adjustable dimension on non-argument", q);
64443220Sbostic 		if(qtype==TYCHAR && (q->vleng==NULL || !ISICON(q->vleng)))
64543220Sbostic 			dclerr("adjustable leng on nonargument", q);
64643220Sbostic 		}
64743220Sbostic 
64843220Sbostic 	chkdim(q);
64943220Sbostic 	}
65043220Sbostic 
65143220Sbostic for (i = 0 ; i < nequiv ; ++i)
65243220Sbostic   if ( (leng = eqvclass[i].eqvleng) != 0 )
65343220Sbostic     {
65443220Sbostic       if (SMALLVAR(leng))
65543220Sbostic 	enlist(leng, NULL, eqvclass + i);
65643220Sbostic       else if (eqvclass[i].init == NO)
65743220Sbostic 	{
65843220Sbostic 	  preven(ALIDOUBLE);
65943220Sbostic 	  prlocvar(memname(STGEQUIV, i), leng);
66043220Sbostic 	  eqvclass[i].inlcomm = YES;
66143220Sbostic 	}
66243220Sbostic       else
66343220Sbostic 	prlocdata(memname(STGEQUIV, i), leng, TYDREAL,
66443220Sbostic 		  eqvclass[i].initoffset, &(eqvclass[i].inlcomm));
66543220Sbostic     }
66643220Sbostic 
66743220Sbostic   outlocvars();
66843220Sbostic #ifdef SDB
66943220Sbostic     if(sdbflag) {
67043220Sbostic       for(p = hashtab ; p<lasthash ; ++p) if(q = p->varp) {
67143220Sbostic 	  qstg = q->vstg;
67243220Sbostic 	  qclass = q->vclass;
67343220Sbostic           if( ONEOF(qclass, M(CLVAR))) {
67443220Sbostic 	     if (! ONEOF(qstg,M(STGCOMMON)|M(STGARG) ) ) namestab(q);
67543220Sbostic 	  }
67643220Sbostic       }
67743220Sbostic     }
67843220Sbostic #endif
67943220Sbostic 
68043220Sbostic   close(vdatafile);
68143220Sbostic   close(vchkfile);
68243220Sbostic   unlink(vdatafname);
68343220Sbostic   unlink(vchkfname);
68443220Sbostic   vdatahwm = 0;
68543220Sbostic }
68643220Sbostic 
68743220Sbostic 
68843220Sbostic 
68943220Sbostic donmlist()
69043220Sbostic {
69143220Sbostic register struct Hashentry *p;
69243220Sbostic register Namep q;
69343220Sbostic 
69443220Sbostic pruse(asmfile, USEINIT);
69543220Sbostic 
69643220Sbostic for(p=hashtab; p<lasthash; ++p)
69743220Sbostic 	if( (q = p->varp) && q->vclass==CLNAMELIST)
69843220Sbostic 		namelist(q);
69943220Sbostic }
70043220Sbostic 
70143220Sbostic 
70243220Sbostic doext()
70343220Sbostic {
70443220Sbostic struct Extsym *p;
70543220Sbostic 
70643220Sbostic for(p = extsymtab ; p<nextext ; ++p)
70743220Sbostic 	prext(p);
70843220Sbostic }
70943220Sbostic 
71043220Sbostic 
71143220Sbostic 
71243220Sbostic 
71343220Sbostic ftnint iarrlen(q)
71443220Sbostic register Namep q;
71543220Sbostic {
71643220Sbostic ftnint leng;
71743220Sbostic 
71843220Sbostic leng = typesize[q->vtype];
71943220Sbostic if(leng <= 0)
72043220Sbostic 	return(-1);
72143220Sbostic if(q->vdim)
72243220Sbostic 	if( ISICON(q->vdim->nelt) )
723*46305Sbostic 		leng *= q->vdim->nelt->constblock.constant.ci;
72443220Sbostic 	else	return(-1);
72543220Sbostic if(q->vleng)
72643220Sbostic 	if( ISICON(q->vleng) )
727*46305Sbostic 		leng *= q->vleng->constblock.constant.ci;
72843220Sbostic 	else 	return(-1);
72943220Sbostic return(leng);
73043220Sbostic }
73143220Sbostic 
73243220Sbostic /* This routine creates a static block representing the namelist.
73343220Sbostic    An equivalent declaration of the structure produced is:
73443220Sbostic 	struct namelist
73543220Sbostic 		{
73643220Sbostic 		char namelistname[16];
73743220Sbostic 		struct namelistentry
73843220Sbostic 			{
73943220Sbostic 			char varname[16];
74043220Sbostic 			char *varaddr;
74143220Sbostic 			int type; # negative means -type= number of chars
74243220Sbostic 			struct dimensions *dimp; # null means scalar
74343220Sbostic 			} names[];
74443220Sbostic 		};
74543220Sbostic 
74643220Sbostic 	struct dimensions
74743220Sbostic 		{
74843220Sbostic 		int numberofdimensions;
74943220Sbostic 		int numberofelements
75043220Sbostic 		int baseoffset;
75143220Sbostic 		int span[numberofdimensions];
75243220Sbostic 		};
75343220Sbostic    where the namelistentry list terminates with a null varname
75443220Sbostic    If dimp is not null, then the corner element of the array is at
75543220Sbostic    varaddr.  However,  the element with subscripts (i1,...,in) is at
75643220Sbostic    varaddr - dimp->baseoffset + sizeoftype * (i1+span[0]*(i2+span[1]*...)
75743220Sbostic */
75843220Sbostic 
75943220Sbostic namelist(np)
76043220Sbostic Namep np;
76143220Sbostic {
76243220Sbostic register chainp q;
76343220Sbostic register Namep v;
76443220Sbostic register struct Dimblock *dp;
76543220Sbostic char *memname();
76643220Sbostic int type, dimno, dimoffset;
76743220Sbostic flag bad;
76843220Sbostic 
76943220Sbostic 
77043220Sbostic preven(ALILONG);
77143220Sbostic fprintf(asmfile, LABELFMT, memname(STGINIT, np->vardesc.varno));
77243220Sbostic putstr(asmfile, varstr(VL, np->varname), 16);
77343220Sbostic dimno = ++lastvarno;
77443220Sbostic dimoffset = 0;
77543220Sbostic bad = NO;
77643220Sbostic 
77743220Sbostic for(q = np->varxptr.namelist ; q ; q = q->nextp)
77843220Sbostic 	{
77943220Sbostic 	vardcl( v = (Namep) (q->datap) );
78043220Sbostic 	type = v->vtype;
78143220Sbostic 	if( ONEOF(v->vstg, MSKSTATIC) )
78243220Sbostic 		{
78343220Sbostic 		preven(ALILONG);
78443220Sbostic 		putstr(asmfile, varstr(VL,v->varname), 16);
78543220Sbostic 		praddr(asmfile, v->vstg, v->vardesc.varno, v->voffset);
78643220Sbostic 		prconi(asmfile, TYINT,
78743220Sbostic 			type==TYCHAR ?
788*46305Sbostic 			    -(v->vleng->constblock.constant.ci) : (ftnint) type);
78943220Sbostic 		if(v->vdim)
79043220Sbostic 			{
79143220Sbostic 			praddr(asmfile, STGINIT, dimno, (ftnint)dimoffset);
79243220Sbostic 			dimoffset += 3 + v->vdim->ndim;
79343220Sbostic 			}
79443220Sbostic 		else
79543220Sbostic 			praddr(asmfile, STGNULL,0,(ftnint) 0);
79643220Sbostic 		}
79743220Sbostic 	else
79843220Sbostic 		{
79943220Sbostic 		dclerr("may not appear in namelist", v);
80043220Sbostic 		bad = YES;
80143220Sbostic 		}
80243220Sbostic 	}
80343220Sbostic 
80443220Sbostic if(bad)
80543220Sbostic 	return;
80643220Sbostic 
80743220Sbostic putstr(asmfile, "", 16);
80843220Sbostic 
80943220Sbostic if(dimoffset > 0)
81043220Sbostic 	{
81143220Sbostic 	fprintf(asmfile, LABELFMT, memname(STGINIT,dimno));
81243220Sbostic 	for(q = np->varxptr.namelist ; q ; q = q->nextp)
81343220Sbostic 		if(dp = q->datap->nameblock.vdim)
81443220Sbostic 			{
81543220Sbostic 			int i;
81643220Sbostic 			prconi(asmfile, TYINT, (ftnint) (dp->ndim) );
81743220Sbostic 			prconi(asmfile, TYINT,
818*46305Sbostic 				(ftnint) (dp->nelt->constblock.constant.ci) );
81943220Sbostic 			prconi(asmfile, TYINT,
820*46305Sbostic 				(ftnint) (dp->baseoffset->constblock.constant.ci));
82143220Sbostic 			for(i=0; i<dp->ndim ; ++i)
82243220Sbostic 				prconi(asmfile, TYINT,
823*46305Sbostic 					dp->dims[i].dimsize->constblock.constant.ci);
82443220Sbostic 			}
82543220Sbostic 	}
82643220Sbostic 
82743220Sbostic }
82843220Sbostic 
82943220Sbostic LOCAL docommon()
83043220Sbostic {
83143220Sbostic register struct Extsym *p;
83243220Sbostic register chainp q;
83343220Sbostic struct Dimblock *t;
83443220Sbostic expptr neltp;
83543220Sbostic register Namep v;
83643220Sbostic ftnint size;
83743220Sbostic int type;
83843220Sbostic 
83943220Sbostic for(p = extsymtab ; p<nextext ; ++p)
84043220Sbostic 	if(p->extstg==STGCOMMON)
84143220Sbostic 		{
84243220Sbostic #ifdef SDB
84343220Sbostic 		if(sdbflag)
84443220Sbostic 			prstab(varstr(XL,p->extname), N_BCOMM, 0, 0);
84543220Sbostic #endif
84643220Sbostic 		for(q = p->extp ; q ; q = q->nextp)
84743220Sbostic 			{
84843220Sbostic 			v = (Namep) (q->datap);
84943220Sbostic 			if(v->vdcldone == NO)
85043220Sbostic 				vardcl(v);
85143220Sbostic 			type = v->vtype;
85243220Sbostic 			if(p->extleng % typealign[type] != 0)
85343220Sbostic 				{
85443220Sbostic 				dclerr("common alignment", v);
85543220Sbostic 				p->extleng = roundup(p->extleng, typealign[type]);
85643220Sbostic 				}
85743220Sbostic 			v->voffset = p->extleng;
85843220Sbostic 			v->vardesc.varno = p - extsymtab;
85943220Sbostic 			if(type == TYCHAR)
860*46305Sbostic 				size = v->vleng->constblock.constant.ci;
86143220Sbostic 			else	size = typesize[type];
86243220Sbostic 			if(t = v->vdim)
86343220Sbostic 				if( (neltp = t->nelt) && ISCONST(neltp) )
864*46305Sbostic 					size *= neltp->constblock.constant.ci;
86543220Sbostic 				else
86643220Sbostic 					dclerr("adjustable array in common", v);
86743220Sbostic 			p->extleng += size;
86843220Sbostic #ifdef SDB
86943220Sbostic 			if(sdbflag)
87043220Sbostic 				{
87143220Sbostic 				namestab(v);
87243220Sbostic 				}
87343220Sbostic #endif
87443220Sbostic 			}
87543220Sbostic 
87643220Sbostic 		frchain( &(p->extp) );
87743220Sbostic #ifdef SDB
87843220Sbostic 		if(sdbflag)
87943220Sbostic 			prstab(varstr(XL,p->extname), N_ECOMM, 0, 0);
88043220Sbostic #endif
88143220Sbostic 		}
88243220Sbostic }
88343220Sbostic 
88443220Sbostic 
88543220Sbostic 
88643220Sbostic 
88743220Sbostic 
88843220Sbostic LOCAL docomleng()
88943220Sbostic {
89043220Sbostic register struct Extsym *p;
89143220Sbostic 
89243220Sbostic for(p = extsymtab ; p < nextext ; ++p)
89343220Sbostic 	if(p->extstg == STGCOMMON)
89443220Sbostic 		{
89543220Sbostic 		if(p->maxleng!=0 && p->extleng!=0 && p->maxleng!=p->extleng
89643220Sbostic 		    && !eqn(XL,"_BLNK__ ",p->extname) )
89743220Sbostic 			warn1("incompatible lengths for common block %s",
89843220Sbostic 				nounder(XL, p->extname) );
89943220Sbostic 		if(p->maxleng < p->extleng)
90043220Sbostic 			p->maxleng = p->extleng;
90143220Sbostic 		p->extleng = 0;
90243220Sbostic 	}
90343220Sbostic }
90443220Sbostic 
90543220Sbostic 
90643220Sbostic 
90743220Sbostic 
90843220Sbostic /* ROUTINES DEALING WITH AUTOMATIC AND TEMPORARY STORAGE */
90943220Sbostic 
91043220Sbostic /*  frees a temporary block  */
91143220Sbostic 
91243220Sbostic frtemp(p)
91343220Sbostic Tempp p;
91443220Sbostic {
91543220Sbostic Addrp t;
91643220Sbostic 
91743220Sbostic if (optimflag)
91843220Sbostic 	{
91943220Sbostic 	if (p->tag != TTEMP)
92043220Sbostic 		badtag ("frtemp",p->tag);
92143220Sbostic 	t = p->memalloc;
92243220Sbostic 	}
92343220Sbostic else
92443220Sbostic 	t = (Addrp) p;
92543220Sbostic 
92643220Sbostic /* restore clobbered character string lengths */
92743220Sbostic if(t->vtype==TYCHAR && t->varleng!=0)
92843220Sbostic 	{
92943220Sbostic 	frexpr(t->vleng);
93043220Sbostic 	t->vleng = ICON(t->varleng);
93143220Sbostic 	}
93243220Sbostic 
93343220Sbostic /* put block on chain of temps to be reclaimed */
93443220Sbostic holdtemps = mkchain(t, holdtemps);
93543220Sbostic }
93643220Sbostic 
93743220Sbostic 
93843220Sbostic 
93943220Sbostic /* allocate an automatic variable slot */
94043220Sbostic 
94143220Sbostic Addrp autovar(nelt, t, lengp)
94243220Sbostic register int nelt, t;
94343220Sbostic expptr lengp;
94443220Sbostic {
94543220Sbostic ftnint leng;
94643220Sbostic register Addrp q;
94743220Sbostic 
94843220Sbostic if(lengp)
94943220Sbostic 	if( ISICON(lengp) )
950*46305Sbostic 		leng = lengp->constblock.constant.ci;
95143220Sbostic 	else	{
95243220Sbostic 		fatal("automatic variable of nonconstant length");
95343220Sbostic 		}
95443220Sbostic else
95543220Sbostic 	leng = typesize[t];
95643220Sbostic autoleng = roundup( autoleng, typealign[t]);
95743220Sbostic 
95843220Sbostic q = ALLOC(Addrblock);
95943220Sbostic q->tag = TADDR;
96043220Sbostic q->vtype = t;
96143220Sbostic if(lengp)
96243220Sbostic 	{
96343220Sbostic 	q->vleng = ICON(leng);
96443220Sbostic 	q->varleng = leng;
96543220Sbostic 	}
96643220Sbostic q->vstg = STGAUTO;
96743220Sbostic q->memno = newlabel();
96843220Sbostic q->ntempelt = nelt;
96943220Sbostic #if TARGET==PDP11 || TARGET==VAX || TARGET == TAHOE
97043220Sbostic 	/* stack grows downward */
97143220Sbostic 	autoleng += nelt*leng;
97243220Sbostic 	q->memoffset = ICON( - autoleng );
97343220Sbostic #else
97443220Sbostic 	q->memoffset = ICON( autoleng );
97543220Sbostic 	autoleng += nelt*leng;
97643220Sbostic #endif
97743220Sbostic 
97843220Sbostic return(q);
97943220Sbostic }
98043220Sbostic 
98143220Sbostic 
98243220Sbostic 
98343220Sbostic /*
98443220Sbostic  *  create a temporary block (TTEMP) when optimizing,
98543220Sbostic  *  an ordinary TADDR block when not optimizing
98643220Sbostic  */
98743220Sbostic 
98843220Sbostic Tempp mktmpn(nelt, type, lengp)
98943220Sbostic int nelt;
99043220Sbostic register int type;
99143220Sbostic expptr lengp;
99243220Sbostic {
99343220Sbostic ftnint leng;
99443220Sbostic chainp p, oldp;
99543220Sbostic register Tempp q;
99643220Sbostic Addrp altemp;
99743220Sbostic 
99843220Sbostic if (! optimflag)
99943220Sbostic 	return ( (Tempp) mkaltmpn(nelt,type,lengp) );
100043220Sbostic if(type==TYUNKNOWN || type==TYERROR)
100143220Sbostic 	badtype("mktmpn", type);
100243220Sbostic 
100343220Sbostic if(type==TYCHAR)
100443220Sbostic 	if( ISICON(lengp) )
1005*46305Sbostic 		leng = lengp->constblock.constant.ci;
100643220Sbostic 	else	{
100743220Sbostic 		err("adjustable length");
100843220Sbostic 		return( (Tempp) errnode() );
100943220Sbostic 		}
101043220Sbostic else
101143220Sbostic 	leng = typesize[type];
101243220Sbostic 
101343220Sbostic q = ALLOC(Tempblock);
101443220Sbostic q->tag = TTEMP;
101543220Sbostic q->vtype = type;
101643220Sbostic if(type == TYCHAR)
101743220Sbostic 	{
101843220Sbostic 	q->vleng = ICON(leng);
101943220Sbostic 	q->varleng = leng;
102043220Sbostic 	}
102143220Sbostic 
102243220Sbostic altemp = ALLOC(Addrblock);
102343220Sbostic altemp->tag = TADDR;
102443220Sbostic altemp->vstg = STGUNKNOWN;
102543220Sbostic q->memalloc = altemp;
102643220Sbostic 
102743220Sbostic q->ntempelt = nelt;
102843220Sbostic q->istemp = YES;
102943220Sbostic return(q);
103043220Sbostic }
103143220Sbostic 
103243220Sbostic 
103343220Sbostic 
103443220Sbostic Addrp mktemp(type, lengp)
103543220Sbostic int type;
103643220Sbostic expptr lengp;
103743220Sbostic {
103843220Sbostic return( (Addrp) mktmpn(1,type,lengp) );
103943220Sbostic }
104043220Sbostic 
104143220Sbostic 
104243220Sbostic 
104343220Sbostic /*  allocate a temporary location for the given temporary block;
104443220Sbostic     if already allocated, return its location  */
104543220Sbostic 
104643220Sbostic Addrp altmpn(tp)
104743220Sbostic Tempp tp;
104843220Sbostic 
104943220Sbostic {
105043220Sbostic Addrp t, q;
105143220Sbostic 
105243220Sbostic if (tp->tag != TTEMP)
105343220Sbostic 	badtag ("altmpn",tp->tag);
105443220Sbostic 
105543220Sbostic t = tp->memalloc;
105643220Sbostic if (t->vstg != STGUNKNOWN)
105743220Sbostic 	{
105843220Sbostic 	if (tp->vtype == TYCHAR)
105943220Sbostic 		{
106043220Sbostic 		/*
106143220Sbostic 		 * Unformatted I/O parameters are treated like character
106243220Sbostic 		 *	strings (sigh) -- propagate type and length.
106343220Sbostic 		 */
106443220Sbostic 		t = (Addrp) cpexpr(t);
106543220Sbostic 		t->vtype = tp->vtype;
106643220Sbostic 		t->vleng = tp->vleng;
106743220Sbostic 		t->varleng = tp->varleng;
106843220Sbostic 		}
106943220Sbostic 	return (t);
107043220Sbostic 	}
107143220Sbostic 
107243220Sbostic q = mkaltmpn (tp->ntempelt, tp->vtype, tp->vleng);
107343220Sbostic cpn (sizeof(struct Addrblock), (char*)q, (char*)t);
107443220Sbostic free ( (charptr) q);
107543220Sbostic return(t);
107643220Sbostic }
107743220Sbostic 
107843220Sbostic 
107943220Sbostic 
108043220Sbostic /*  create and allocate space immediately for a temporary  */
108143220Sbostic 
108243220Sbostic Addrp mkaltemp(type,lengp)
108343220Sbostic int type;
108443220Sbostic expptr lengp;
108543220Sbostic {
108643220Sbostic return (mkaltmpn(1,type,lengp));
108743220Sbostic }
108843220Sbostic 
108943220Sbostic 
109043220Sbostic 
109143220Sbostic Addrp mkaltmpn(nelt,type,lengp)
109243220Sbostic int nelt;
109343220Sbostic register int type;
109443220Sbostic expptr lengp;
109543220Sbostic {
109643220Sbostic ftnint leng;
109743220Sbostic chainp p, oldp;
109843220Sbostic register Addrp q;
109943220Sbostic 
110043220Sbostic if(type==TYUNKNOWN || type==TYERROR)
110143220Sbostic 	badtype("mkaltmpn", type);
110243220Sbostic 
110343220Sbostic if(type==TYCHAR)
110443220Sbostic 	if( ISICON(lengp) )
1105*46305Sbostic 		leng = lengp->constblock.constant.ci;
110643220Sbostic 	else	{
110743220Sbostic 		err("adjustable length");
110843220Sbostic 		return( (Addrp) errnode() );
110943220Sbostic 		}
111043220Sbostic 
111143220Sbostic /*
111243220Sbostic  * if a temporary of appropriate shape is on the templist,
111343220Sbostic  * remove it from the list and return it
111443220Sbostic  */
111543220Sbostic 
111643220Sbostic #ifdef notdef
111743220Sbostic /*
111843220Sbostic  * This code is broken until SKFRTEMP slots can be processed in putopt()
111943220Sbostic  *	instead of in optimize() -- all kinds of things in putpcc.c can
112043220Sbostic  *	bomb because of this.  Sigh.
112143220Sbostic  */
112243220Sbostic for(oldp=CHNULL, p=templist  ;  p  ;  oldp=p, p=p->nextp)
112343220Sbostic 	{
112443220Sbostic 	q = (Addrp) (p->datap);
112543220Sbostic 	if(q->vtype==type && q->ntempelt==nelt &&
1126*46305Sbostic 	    (type!=TYCHAR || q->vleng->constblock.constant.ci==leng) )
112743220Sbostic 		{
112843220Sbostic 		if(oldp)
112943220Sbostic 			oldp->nextp = p->nextp;
113043220Sbostic 		else
113143220Sbostic 			templist = p->nextp;
113243220Sbostic 		free( (charptr) p);
113343220Sbostic 
113443220Sbostic 		if (debugflag[14])
113543220Sbostic 			fprintf(diagfile,"mkaltmpn reusing offset %d\n",
1136*46305Sbostic 				q->memoffset->constblock.constant.ci);
113743220Sbostic 		return(q);
113843220Sbostic 		}
113943220Sbostic 	}
114043220Sbostic #endif notdef
114143220Sbostic q = autovar(nelt, type, lengp);
114243220Sbostic q->istemp = YES;
114343220Sbostic 
114443220Sbostic if (debugflag[14])
114543220Sbostic 	fprintf(diagfile,"mkaltmpn new offset %d\n",
1146*46305Sbostic 		q->memoffset->constblock.constant.ci);
114743220Sbostic return(q);
114843220Sbostic }
114943220Sbostic 
115043220Sbostic 
115143220Sbostic 
115243220Sbostic /*  The following routine is a patch which is only needed because the	*/
115343220Sbostic /*  code for processing actual arguments for calls does not allocate	*/
115443220Sbostic /*  the temps it needs before optimization takes place.  A better	*/
115543220Sbostic /*  solution is possible, but I do not have the time to implement it	*/
115643220Sbostic /*  now.								*/
115743220Sbostic /*									*/
115843220Sbostic /*					Robert P. Corbett		*/
115943220Sbostic 
116043220Sbostic Addrp
116143220Sbostic mkargtemp(type, lengp)
116243220Sbostic int type;
116343220Sbostic expptr lengp;
116443220Sbostic {
116543220Sbostic   ftnint leng;
116643220Sbostic   chainp oldp, p;
116743220Sbostic   Addrp q;
116843220Sbostic 
116943220Sbostic   if (type == TYUNKNOWN || type == TYERROR)
117043220Sbostic     badtype("mkargtemp", type);
117143220Sbostic 
117243220Sbostic   if (type == TYCHAR)
117343220Sbostic     {
117443220Sbostic       if (ISICON(lengp))
1175*46305Sbostic 	leng = lengp->constblock.constant.ci;
117643220Sbostic       else
117743220Sbostic 	{
117843220Sbostic 	  err("adjustable length");
117943220Sbostic 	  return ((Addrp) errnode());
118043220Sbostic 	}
118143220Sbostic     }
118243220Sbostic 
118343220Sbostic   oldp = CHNULL;
118443220Sbostic   p = argtemplist;
118543220Sbostic 
118643220Sbostic   while (p)
118743220Sbostic     {
118843220Sbostic       q = (Addrp) (p->datap);
118943220Sbostic       if (q->vtype == type
1190*46305Sbostic 	  && (type != TYCHAR || q->vleng->constblock.constant.ci == leng))
119143220Sbostic 	{
119243220Sbostic 	  if (oldp)
119343220Sbostic 	    oldp->nextp = p->nextp;
119443220Sbostic 	  else
119543220Sbostic 	    argtemplist = p->nextp;
119643220Sbostic 
119743220Sbostic 	  p->nextp = activearglist;
119843220Sbostic 	  activearglist = p;
119943220Sbostic 
120043220Sbostic 	  return ((Addrp) cpexpr(q));
120143220Sbostic 	}
120243220Sbostic 
120343220Sbostic       oldp = p;
120443220Sbostic       p = p->nextp;
120543220Sbostic     }
120643220Sbostic 
120743220Sbostic   q = autovar(1, type, lengp);
120843220Sbostic   activearglist = mkchain(q, activearglist);
120943220Sbostic   return ((Addrp) cpexpr(q));
121043220Sbostic }
121143220Sbostic 
121243220Sbostic /* VARIOUS ROUTINES FOR PROCESSING DECLARATIONS */
121343220Sbostic 
121443220Sbostic struct Extsym *comblock(len, s)
121543220Sbostic register int len;
121643220Sbostic register char *s;
121743220Sbostic {
121843220Sbostic struct Extsym *p;
121943220Sbostic 
122043220Sbostic if(len == 0)
122143220Sbostic 	{
122243220Sbostic 	s = BLANKCOMMON;
122343220Sbostic 	len = strlen(s);
122443220Sbostic 	}
122543220Sbostic p = mkext( varunder(len, s) );
122643220Sbostic if(p->extstg == STGUNKNOWN)
122743220Sbostic 	p->extstg = STGCOMMON;
122843220Sbostic else if(p->extstg != STGCOMMON)
122943220Sbostic 	{
123043220Sbostic 	errstr("%s cannot be a common block name", s);
123143220Sbostic 	return(0);
123243220Sbostic 	}
123343220Sbostic 
123443220Sbostic return( p );
123543220Sbostic }
123643220Sbostic 
123743220Sbostic 
123843220Sbostic incomm(c, v)
123943220Sbostic struct Extsym *c;
124043220Sbostic Namep v;
124143220Sbostic {
124243220Sbostic if(v->vstg != STGUNKNOWN)
124343220Sbostic 	dclerr("incompatible common declaration", v);
124443220Sbostic else
124543220Sbostic 	{
124643220Sbostic 	if(c == (struct Extsym *) 0)
124743220Sbostic 		return;		/* Illegal common block name upstream */
124843220Sbostic 	v->vstg = STGCOMMON;
124943220Sbostic 	c->extp = hookup(c->extp, mkchain(v,CHNULL) );
125043220Sbostic 	}
125143220Sbostic }
125243220Sbostic 
125343220Sbostic 
125443220Sbostic 
125543220Sbostic 
125643220Sbostic settype(v, type, length)
125743220Sbostic register Namep  v;
125843220Sbostic register int type;
125943220Sbostic register int length;
126043220Sbostic {
126143220Sbostic if(type == TYUNKNOWN)
126243220Sbostic 	return;
126343220Sbostic 
126443220Sbostic if(type==TYSUBR && v->vtype!=TYUNKNOWN && v->vstg==STGARG)
126543220Sbostic 	{
126643220Sbostic 	v->vtype = TYSUBR;
126743220Sbostic 	frexpr(v->vleng);
126843220Sbostic 	}
126943220Sbostic else if(type < 0)	/* storage class set */
127043220Sbostic 	{
127143220Sbostic 	if(v->vstg == STGUNKNOWN)
127243220Sbostic 		v->vstg = - type;
127343220Sbostic 	else if(v->vstg != -type)
127443220Sbostic 		dclerr("incompatible storage declarations", v);
127543220Sbostic 	}
127643220Sbostic else if(v->vtype == TYUNKNOWN)
127743220Sbostic 	{
127843220Sbostic 	if( (v->vtype = lengtype(type, length))==TYCHAR && length>=0)
127943220Sbostic 		v->vleng = ICON(length);
128043220Sbostic 	}
1281*46305Sbostic else if(v->vtype!=type || (type==TYCHAR && v->vleng->constblock.constant.ci!=length) )
128243220Sbostic 	dclerr("incompatible type declarations", v);
128343220Sbostic }
128443220Sbostic 
128543220Sbostic 
128643220Sbostic 
128743220Sbostic 
128843220Sbostic 
128943220Sbostic lengtype(type, length)
129043220Sbostic register int type;
129143220Sbostic register int length;
129243220Sbostic {
129343220Sbostic switch(type)
129443220Sbostic 	{
129543220Sbostic 	case TYREAL:
129643220Sbostic 		if(length == 8)
129743220Sbostic 			return(TYDREAL);
129843220Sbostic 		if(length == 4)
129943220Sbostic 			goto ret;
130043220Sbostic 		break;
130143220Sbostic 
130243220Sbostic 	case TYCOMPLEX:
130343220Sbostic 		if(length == 16)
130443220Sbostic 			return(TYDCOMPLEX);
130543220Sbostic 		if(length == 8)
130643220Sbostic 			goto ret;
130743220Sbostic 		break;
130843220Sbostic 
130943220Sbostic 	case TYSHORT:
131043220Sbostic 	case TYDREAL:
131143220Sbostic 	case TYDCOMPLEX:
131243220Sbostic 	case TYCHAR:
131343220Sbostic 	case TYUNKNOWN:
131443220Sbostic 	case TYSUBR:
131543220Sbostic 	case TYERROR:
131643220Sbostic 		goto ret;
131743220Sbostic 
131843220Sbostic 	case TYLOGICAL:
131943220Sbostic 		if(length == typesize[TYLOGICAL])
132043220Sbostic 			goto ret;
132143220Sbostic 		break;
132243220Sbostic 
132343220Sbostic 	case TYLONG:
132443220Sbostic 		if(length == 0 )
132543220Sbostic 			return(tyint);
132643220Sbostic 		if(length == 2)
132743220Sbostic 			return(TYSHORT);
132843220Sbostic 		if(length == 4 )
132943220Sbostic 			goto ret;
133043220Sbostic 		break;
133143220Sbostic 	default:
133243220Sbostic 		badtype("lengtype", type);
133343220Sbostic 	}
133443220Sbostic 
133543220Sbostic if(length != 0)
133643220Sbostic 	err("incompatible type-length combination");
133743220Sbostic 
133843220Sbostic ret:
133943220Sbostic 	return(type);
134043220Sbostic }
134143220Sbostic 
134243220Sbostic 
134343220Sbostic 
134443220Sbostic 
134543220Sbostic 
134643220Sbostic setintr(v)
134743220Sbostic register Namep  v;
134843220Sbostic {
134943220Sbostic register int k;
135043220Sbostic 
135143220Sbostic if(v->vstg == STGUNKNOWN)
135243220Sbostic 	v->vstg = STGINTR;
135343220Sbostic else if(v->vstg!=STGINTR)
135443220Sbostic 	dclerr("incompatible use of intrinsic function", v);
135543220Sbostic if(v->vclass==CLUNKNOWN)
135643220Sbostic 	v->vclass = CLPROC;
135743220Sbostic if(v->vprocclass == PUNKNOWN)
135843220Sbostic 	v->vprocclass = PINTRINSIC;
135943220Sbostic else if(v->vprocclass != PINTRINSIC)
136043220Sbostic 	dclerr("invalid intrinsic declaration", v);
136143220Sbostic if(k = intrfunct(v->varname))
136243220Sbostic 	v->vardesc.varno = k;
136343220Sbostic else
136443220Sbostic 	dclerr("unknown intrinsic function", v);
136543220Sbostic }
136643220Sbostic 
136743220Sbostic 
136843220Sbostic 
136943220Sbostic setext(v)
137043220Sbostic register Namep  v;
137143220Sbostic {
137243220Sbostic if(v->vclass == CLUNKNOWN)
137343220Sbostic 	v->vclass = CLPROC;
137443220Sbostic else if(v->vclass != CLPROC)
137543220Sbostic 	dclerr("conflicting declarations", v);
137643220Sbostic 
137743220Sbostic if(v->vprocclass == PUNKNOWN)
137843220Sbostic 	v->vprocclass = PEXTERNAL;
137943220Sbostic else if(v->vprocclass != PEXTERNAL)
138043220Sbostic 	dclerr("conflicting declarations", v);
138143220Sbostic }
138243220Sbostic 
138343220Sbostic 
138443220Sbostic 
138543220Sbostic 
138643220Sbostic /* create dimensions block for array variable */
138743220Sbostic 
138843220Sbostic setbound(v, nd, dims)
138943220Sbostic register Namep  v;
139043220Sbostic int nd;
139143220Sbostic struct { expptr lb, ub; } dims[ ];
139243220Sbostic {
139343220Sbostic register expptr q, t;
139443220Sbostic register struct Dimblock *p;
139543220Sbostic int i;
139643220Sbostic 
139743220Sbostic if(v->vclass == CLUNKNOWN)
139843220Sbostic 	v->vclass = CLVAR;
139943220Sbostic else if(v->vclass != CLVAR)
140043220Sbostic 	{
140143220Sbostic 	dclerr("only variables may be arrays", v);
140243220Sbostic 	return;
140343220Sbostic 	}
140443220Sbostic if(v->vdim)
140543220Sbostic 	{
140643220Sbostic 	dclerr("redimensioned array", v);
140743220Sbostic 	return;
140843220Sbostic 	}
140943220Sbostic 
141043220Sbostic v->vdim = p = (struct Dimblock *)
141143220Sbostic 		ckalloc( sizeof(int) + (3+6*nd)*sizeof(expptr) );
141243220Sbostic p->ndim = nd;
141343220Sbostic p->nelt = ICON(1);
141443220Sbostic 
141543220Sbostic for(i=0 ; i<nd ; ++i)
141643220Sbostic 	{
141743220Sbostic #ifdef SDB
141843220Sbostic         if(sdbflag) {
141943220Sbostic /* Save the bounds trees built up by the grammar routines for use in stabs */
142043220Sbostic 
142143220Sbostic 		if(dims[i].lb == NULL) p->dims[i].lb=ICON(1);
142243220Sbostic         	else p->dims[i].lb= (expptr) cpexpr(dims[i].lb);
142343220Sbostic                 if(ISCONST(p->dims[i].lb)) p->dims[i].lbaddr = (expptr) PNULL;
142443220Sbostic                 else p->dims[i].lbaddr = (expptr) autovar(1, tyint, PNULL);
142543220Sbostic 
142643220Sbostic 		if(dims[i].ub == NULL) p->dims[i].ub=ICON(1);
142743220Sbostic         	else p->dims[i].ub = (expptr) cpexpr(dims[i].ub);
142843220Sbostic                 if(ISCONST(p->dims[i].ub)) p->dims[i].ubaddr = (expptr) PNULL;
142943220Sbostic                 else p->dims[i].ubaddr = (expptr) autovar(1, tyint, PNULL);
143043220Sbostic 	}
143143220Sbostic #endif
143243220Sbostic 	if( (q = dims[i].ub) == NULL)
143343220Sbostic 		{
143443220Sbostic 		if(i == nd-1)
143543220Sbostic 			{
143643220Sbostic 			frexpr(p->nelt);
143743220Sbostic 			p->nelt = NULL;
143843220Sbostic 			}
143943220Sbostic 		else
144043220Sbostic 			err("only last bound may be asterisk");
144143220Sbostic 		p->dims[i].dimsize = ICON(1);;
144243220Sbostic 		p->dims[i].dimexpr = NULL;
144343220Sbostic 		}
144443220Sbostic 	else
144543220Sbostic 		{
144643220Sbostic 		if(dims[i].lb)
144743220Sbostic 			{
144843220Sbostic 			q = mkexpr(OPMINUS, q, cpexpr(dims[i].lb));
144943220Sbostic 			q = mkexpr(OPPLUS, q, ICON(1) );
145043220Sbostic 			}
145143220Sbostic 		if( ISCONST(q) )
145243220Sbostic 			{
145343220Sbostic 			if (!ISINT(q->headblock.vtype)) {
145443220Sbostic 			   dclerr("dimension bounds must be integer expression", v);
145543220Sbostic 			   frexpr(q);
145643220Sbostic 			   q = ICON(0);
145743220Sbostic 			   }
1458*46305Sbostic 			if ( q->constblock.constant.ci <= 0)
145943220Sbostic 			   {
146043220Sbostic 			   dclerr("array bounds out of sequence", v);
146143220Sbostic 			   frexpr(q);
146243220Sbostic 			   q = ICON(0);
146343220Sbostic 			   }
146443220Sbostic 			p->dims[i].dimsize = q;
146543220Sbostic 			p->dims[i].dimexpr = (expptr) PNULL;
146643220Sbostic 			}
146743220Sbostic 		else	{
146843220Sbostic 			p->dims[i].dimsize = (expptr) autovar(1, tyint, PNULL);
146943220Sbostic 			p->dims[i].dimexpr = q;
147043220Sbostic 			}
147143220Sbostic 		if(p->nelt)
147243220Sbostic 			p->nelt = mkexpr(OPSTAR, p->nelt,
147343220Sbostic 					cpexpr(p->dims[i].dimsize) );
147443220Sbostic 		}
147543220Sbostic 	}
147643220Sbostic 
147743220Sbostic q = dims[nd-1].lb;
147843220Sbostic if(q == NULL)
147943220Sbostic 	q = ICON(1);
148043220Sbostic 
148143220Sbostic for(i = nd-2 ; i>=0 ; --i)
148243220Sbostic 	{
148343220Sbostic 	t = dims[i].lb;
148443220Sbostic 	if(t == NULL)
148543220Sbostic 		t = ICON(1);
148643220Sbostic 	if(p->dims[i].dimsize)
148743220Sbostic 		q = mkexpr(OPPLUS, t, mkexpr(OPSTAR, cpexpr(p->dims[i].dimsize), q) );
148843220Sbostic 	}
148943220Sbostic 
149043220Sbostic if( ISCONST(q) )
149143220Sbostic 	{
149243220Sbostic 	p->baseoffset = q;
149343220Sbostic 	p->basexpr = NULL;
149443220Sbostic 	}
149543220Sbostic else
149643220Sbostic 	{
149743220Sbostic 	p->baseoffset = (expptr) autovar(1, tyint, PNULL);
149843220Sbostic 	p->basexpr = q;
149943220Sbostic 	}
150043220Sbostic }
150143220Sbostic 
150243220Sbostic 
150343220Sbostic 
150443220Sbostic /*
150543220Sbostic  * Check the dimensions of q to ensure that they are appropriately defined.
150643220Sbostic  */
150743220Sbostic LOCAL chkdim(q)
150843220Sbostic register Namep q;
150943220Sbostic {
151043220Sbostic   register struct Dimblock *p;
151143220Sbostic   register int i;
151243220Sbostic   expptr e;
151343220Sbostic 
151443220Sbostic   if (q == NULL)
151543220Sbostic     return;
151643220Sbostic   if (q->vclass != CLVAR)
151743220Sbostic     return;
151843220Sbostic   if (q->vdim == NULL)
151943220Sbostic     return;
152043220Sbostic   p = q->vdim;
152143220Sbostic   for (i = 0; i < p->ndim; ++i)
152243220Sbostic     {
152343220Sbostic #ifdef SDB
152443220Sbostic       if (sdbflag)
152543220Sbostic 	{
152643220Sbostic 	  if (e = p->dims[i].lb)
152743220Sbostic 	    chkdime(e, q);
152843220Sbostic 	  if (e = p->dims[i].ub)
152943220Sbostic 	    chkdime(e, q);
153043220Sbostic 	}
153143220Sbostic       else
153243220Sbostic #endif SDB
153343220Sbostic       if (e = p->dims[i].dimexpr)
153443220Sbostic 	chkdime(e, q);
153543220Sbostic     }
153643220Sbostic }
153743220Sbostic 
153843220Sbostic 
153943220Sbostic 
154043220Sbostic /*
154143220Sbostic  * The actual checking for chkdim() -- examines each expression.
154243220Sbostic  */
154343220Sbostic LOCAL chkdime(expr, q)
154443220Sbostic expptr expr;
154543220Sbostic Namep q;
154643220Sbostic {
154743220Sbostic   register expptr e;
154843220Sbostic 
154943220Sbostic   e = fixtype(cpexpr(expr));
155043220Sbostic   if (!ISINT(e->exprblock.vtype))
155143220Sbostic     dclerr("non-integer dimension", q);
155243220Sbostic   else if (!safedim(e))
155343220Sbostic     dclerr("undefined dimension", q);
155443220Sbostic   frexpr(e);
155543220Sbostic   return;
155643220Sbostic }
155743220Sbostic 
155843220Sbostic 
155943220Sbostic 
156043220Sbostic /*
156143220Sbostic  * A recursive routine to find undefined variables in dimension expressions.
156243220Sbostic  */
156343220Sbostic LOCAL safedim(e)
156443220Sbostic expptr e;
156543220Sbostic {
156643220Sbostic   chainp cp;
156743220Sbostic 
156843220Sbostic   if (e == NULL)
156943220Sbostic     return 1;
157043220Sbostic   switch (e->tag)
157143220Sbostic     {
157243220Sbostic       case TEXPR:
157343220Sbostic 	if (e->exprblock.opcode == OPCALL || e->exprblock.opcode == OPCCALL)
157443220Sbostic 	  return 0;
157543220Sbostic 	return safedim(e->exprblock.leftp) && safedim(e->exprblock.rightp);
157643220Sbostic       case TADDR:
157743220Sbostic 	switch (e->addrblock.vstg)
157843220Sbostic 	  {
157943220Sbostic 	    case STGCOMMON:
158043220Sbostic 	    case STGARG:
158143220Sbostic 	    case STGCONST:
158243220Sbostic 	    case STGEQUIV:
158343220Sbostic 	      if (e->addrblock.isarray)
158443220Sbostic 		return 0;
158543220Sbostic 	      return safedim(e->addrblock.memoffset);
158643220Sbostic 	    default:
158743220Sbostic 	      return 0;
158843220Sbostic 	  }
158943220Sbostic       case TCONST:
159043220Sbostic       case TTEMP:
159143220Sbostic 	return 1;
159243220Sbostic     }
159343220Sbostic   return 0;
159443220Sbostic }
159543220Sbostic 
159643220Sbostic 
159743220Sbostic 
159843220Sbostic LOCAL enlist(size, np, ep)
159943220Sbostic ftnint size;
160043220Sbostic Namep np;
160143220Sbostic struct Equivblock *ep;
160243220Sbostic {
160343220Sbostic   register sizelist *sp;
160443220Sbostic   register sizelist *t;
160543220Sbostic   register varlist *p;
160643220Sbostic 
160743220Sbostic   sp = varsizes;
160843220Sbostic 
160943220Sbostic   if (sp == NULL)
161043220Sbostic     {
161143220Sbostic       sp = ALLOC(SizeList);
161243220Sbostic       sp->size = size;
161343220Sbostic       varsizes = sp;
161443220Sbostic     }
161543220Sbostic   else
161643220Sbostic     {
161743220Sbostic       while (sp->size != size)
161843220Sbostic 	{
161943220Sbostic 	  if (sp->next != NULL && sp->next->size <= size)
162043220Sbostic 	    sp = sp->next;
162143220Sbostic 	  else
162243220Sbostic 	    {
162343220Sbostic 	      t = sp;
162443220Sbostic 	      sp = ALLOC(SizeList);
162543220Sbostic 	      sp->size = size;
162643220Sbostic 	      sp->next = t->next;
162743220Sbostic 	      t->next = sp;
162843220Sbostic 	    }
162943220Sbostic 	}
163043220Sbostic     }
163143220Sbostic 
163243220Sbostic   p = ALLOC(VarList);
163343220Sbostic   p->next = sp->vars;
163443220Sbostic   p->np = np;
163543220Sbostic   p->ep = ep;
163643220Sbostic 
163743220Sbostic   sp->vars = p;
163843220Sbostic 
163943220Sbostic   return;
164043220Sbostic }
164143220Sbostic 
164243220Sbostic 
164343220Sbostic 
164443220Sbostic outlocvars()
164543220Sbostic {
164643220Sbostic 
164743220Sbostic   register varlist *first, *last;
164843220Sbostic   register varlist *vp, *t;
164943220Sbostic   register sizelist *sp, *sp1;
165043220Sbostic   register Namep np;
165143220Sbostic   register struct Equivblock *ep;
165243220Sbostic   register int i;
165343220Sbostic   register int alt;
165443220Sbostic   register int type;
165543220Sbostic   char sname[100];
165643220Sbostic   char setbuff[100];
165743220Sbostic 
165843220Sbostic   sp = varsizes;
165943220Sbostic   if (sp == NULL)
166043220Sbostic     return;
166143220Sbostic 
166243220Sbostic   vp = sp->vars;
166343220Sbostic   if (vp->np != NULL)
166443220Sbostic     {
166543220Sbostic       np = vp->np;
166643220Sbostic       sprintf(setbuff, "\t.set\tv.%d,v.%d\n", bsslabel,
166743220Sbostic 	      np->vardesc.varno);
166843220Sbostic     }
166943220Sbostic   else
167043220Sbostic     {
167143220Sbostic       i = vp->ep - eqvclass;
167243220Sbostic       sprintf(setbuff, "\t.set\tv.%d,q.%d\n", bsslabel, i + eqvstart);
167343220Sbostic     }
167443220Sbostic 
167543220Sbostic   first = last = NULL;
167643220Sbostic   alt = NO;
167743220Sbostic 
167843220Sbostic   while (sp != NULL)
167943220Sbostic     {
168043220Sbostic       vp = sp->vars;
168143220Sbostic       while (vp != NULL)
168243220Sbostic 	{
168343220Sbostic 	  t = vp->next;
168443220Sbostic 	  if (alt == YES)
168543220Sbostic 	    {
168643220Sbostic 	      alt = NO;
168743220Sbostic 	      vp->next = first;
168843220Sbostic 	      first = vp;
168943220Sbostic 	    }
169043220Sbostic 	  else
169143220Sbostic 	    {
169243220Sbostic 	      alt = YES;
169343220Sbostic 	      if (last != NULL)
169443220Sbostic 	        last->next = vp;
169543220Sbostic 	      else
169643220Sbostic 		first = vp;
169743220Sbostic 	      vp->next = NULL;
169843220Sbostic 	      last = vp;
169943220Sbostic 	    }
170043220Sbostic 	  vp = t;
170143220Sbostic 	}
170243220Sbostic       sp1 = sp;
170343220Sbostic       sp = sp->next;
170443220Sbostic       free((char *) sp1);
170543220Sbostic     }
170643220Sbostic 
170743220Sbostic   vp = first;
170843220Sbostic   while(vp != NULL)
170943220Sbostic     {
171043220Sbostic       if (vp->np != NULL)
171143220Sbostic 	{
171243220Sbostic 	  np = vp->np;
171343220Sbostic 	  sprintf(sname, "v.%d", np->vardesc.varno);
171443220Sbostic 	  pralign(typealign[np->vtype]);
171543220Sbostic 	  if (np->init)
171643220Sbostic 	    prlocdata(sname, np->varsize, np->vtype, np->initoffset,
171743220Sbostic 		      &(np->inlcomm));
171843220Sbostic 	  else
171943220Sbostic 	    {
172043220Sbostic 	      if (typealign[np->vtype] == 1)
172143220Sbostic 		  pralign(3);
172243220Sbostic 	      fprintf(initfile, "%s:\n\t.space\t%d\n", sname,
172343220Sbostic 		      np->varsize);
172443220Sbostic 	    }
172543220Sbostic 	  np->inlcomm = NO;
172643220Sbostic 	}
172743220Sbostic       else
172843220Sbostic 	{
172943220Sbostic 	  ep = vp->ep;
173043220Sbostic 	  i = ep - eqvclass;
173143220Sbostic 	  if (ep->eqvleng >= 8)
173243220Sbostic 	    type = TYDREAL;
173343220Sbostic 	  else if (ep->eqvleng >= 4)
173443220Sbostic 	    type = TYLONG;
173543220Sbostic 	  else if (ep->eqvleng >= 2)
173643220Sbostic 	    type = TYSHORT;
173743220Sbostic 	  else
173843220Sbostic 	    type = TYCHAR;
173943220Sbostic 	  sprintf(sname, "q.%d", i + eqvstart);
174043220Sbostic 	  if (ep->init)
174143220Sbostic 	    prlocdata(sname, ep->eqvleng, type, ep->initoffset,
174243220Sbostic 		      &(ep->inlcomm));
174343220Sbostic 	  else
174443220Sbostic 	    {
174543220Sbostic 	      pralign(typealign[type]);
174643220Sbostic 	      fprintf(initfile, "%s:\n\t.space\t%d\n", sname, ep->eqvleng);
174743220Sbostic 	    }
174843220Sbostic 	  ep->inlcomm = NO;
174943220Sbostic 	}
175043220Sbostic       t = vp;
175143220Sbostic       vp = vp->next;
175243220Sbostic       free((char *) t);
175343220Sbostic     }
175443220Sbostic   fprintf(initfile, "%s\n", setbuff);
175543220Sbostic   return;
175643220Sbostic }
1757