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