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