xref: /csrg-svn/usr.bin/f77/pass1.vax/equiv.c (revision 47955)
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%
622806Smckusick  */
722806Smckusick 
822806Smckusick #ifndef lint
9*47955Sbostic static char sccsid[] = "@(#)equiv.c	5.3 (Berkeley) 04/12/91";
10*47955Sbostic #endif /* not lint */
1122806Smckusick 
1222806Smckusick /*
1322806Smckusick  * equiv.c
1422806Smckusick  *
1522806Smckusick  * Routines related to equivalence class processing, f77 compiler, 4.2 BSD.
1622806Smckusick  *
1722806Smckusick  * University of Utah CS Dept modification history:
1822806Smckusick  *
1922806Smckusick  * Revision 3.2  85/01/14  00:14:12  donn
2022806Smckusick  * Fixed bug in eqvcommon that was causing the calculations of multilevel
2122806Smckusick  * equivalences to be screwed up.
2222806Smckusick  *
2322806Smckusick  * Revision 3.1  84/10/13  01:16:08  donn
2422806Smckusick  * Installed Jerry Berkman's version; added UofU comment header.
2522806Smckusick  *
2622806Smckusick  */
2722806Smckusick 
2822806Smckusick 
2922806Smckusick #include "defs.h"
3022806Smckusick 
3122806Smckusick #ifdef SDB
3222806Smckusick #	include <a.out.h>
3322806Smckusick #	ifndef N_SO
3422806Smckusick #		include <stab.h>
3522806Smckusick #	endif
3622806Smckusick #endif
3722806Smckusick 
3822806Smckusick /* called at end of declarations section to process chains
3922806Smckusick    created by EQUIVALENCE statements
4022806Smckusick  */
4122806Smckusick 
doequiv()4222806Smckusick doequiv()
4322806Smckusick {
4422806Smckusick register int i;
4522806Smckusick int inequiv, comno, ovarno;
4622806Smckusick ftnint comoffset, offset, leng;
4722806Smckusick register struct Equivblock *p;
4822806Smckusick register struct Eqvchain *q;
4922806Smckusick struct Primblock *itemp;
5022806Smckusick register Namep np;
5122806Smckusick expptr offp, suboffset();
5222806Smckusick int ns, nsubs();
5322806Smckusick chainp cp;
5422806Smckusick char *memname();
5522806Smckusick int doeqverr = 0;
5622806Smckusick 
5722806Smckusick for(i = 0 ; i < nequiv ; ++i)
5822806Smckusick 	{
5922806Smckusick 	p = &eqvclass[i];
6022806Smckusick 	p->eqvbottom = p->eqvtop = 0;
6122806Smckusick 	comno = -1;
6222806Smckusick 
6322806Smckusick 	for(q = p->equivs ; q ; q = q->eqvnextp)
6422806Smckusick 		{
6522806Smckusick 		offset = 0;
6622806Smckusick 		itemp = q->eqvitem.eqvlhs;
6722806Smckusick 		if( itemp == NULL ) fatal("error processing equivalence");
6822806Smckusick 		equivdcl = YES;
6922806Smckusick 		vardcl(np = itemp->namep);
7022806Smckusick 		equivdcl = NO;
7122806Smckusick 		if(itemp->argsp || itemp->fcharp)
7222806Smckusick 			{
7322806Smckusick 			if(np->vdim!=NULL && np->vdim->ndim>1 &&
7422806Smckusick 			   nsubs(itemp->argsp)==1 )
7522806Smckusick 				{
7622806Smckusick 				if(! ftn66flag)
7722806Smckusick 					warn("1-dim subscript in EQUIVALENCE");
7822806Smckusick 				cp = NULL;
7922806Smckusick 				ns = np->vdim->ndim;
8022806Smckusick 				while(--ns > 0)
8122806Smckusick 					cp = mkchain( ICON(1), cp);
8222806Smckusick 				itemp->argsp->listp->nextp = cp;
8322806Smckusick 				}
8422806Smckusick 
8522806Smckusick 			offp = suboffset(itemp);
8622806Smckusick 			if(ISICON(offp))
8733256Sbostic 				offset = offp->constblock.constant.ci;
8822806Smckusick 			else	{
8922806Smckusick 				dclerr("illegal subscript in equivalence ",
9022806Smckusick 					np);
9122806Smckusick 				np = NULL;
9222806Smckusick 				doeqverr = 1;
9322806Smckusick 				}
9422806Smckusick 			frexpr(offp);
9522806Smckusick 			}
9622806Smckusick 		frexpr(itemp);
9722806Smckusick 
9822806Smckusick 		if(np && (leng = iarrlen(np))<0)
9922806Smckusick 			{
10022806Smckusick 			dclerr("argument in equivalence", np);
10122806Smckusick 			np = NULL;
10222806Smckusick 			doeqverr =1;
10322806Smckusick 			}
10422806Smckusick 
10522806Smckusick 		if(np) switch(np->vstg)
10622806Smckusick 			{
10722806Smckusick 			case STGUNKNOWN:
10822806Smckusick 			case STGBSS:
10922806Smckusick 			case STGEQUIV:
11022806Smckusick 				break;
11122806Smckusick 
11222806Smckusick 			case STGCOMMON:
11322806Smckusick 				comno = np->vardesc.varno;
11422806Smckusick 				comoffset = np->voffset + offset;
11522806Smckusick 				break;
11622806Smckusick 
11722806Smckusick 			default:
11822806Smckusick 				dclerr("bad storage class in equivalence", np);
11922806Smckusick 				np = NULL;
12022806Smckusick 				doeqverr = 1;
12122806Smckusick 				break;
12222806Smckusick 			}
12322806Smckusick 
12422806Smckusick 		if(np)
12522806Smckusick 			{
12622806Smckusick 			q->eqvoffset = offset;
12722806Smckusick 			p->eqvbottom = lmin(p->eqvbottom, -offset);
12822806Smckusick 			p->eqvtop = lmax(p->eqvtop, leng-offset);
12922806Smckusick 			}
13022806Smckusick 		q->eqvitem.eqvname = np;
13122806Smckusick 		}
13222806Smckusick 
13322806Smckusick 	if(comno >= 0)
13422806Smckusick 		eqvcommon(p, comno, comoffset);
13522806Smckusick 	else  for(q = p->equivs ; q ; q = q->eqvnextp)
13622806Smckusick 		{
13722806Smckusick 		if(np = q->eqvitem.eqvname)
13822806Smckusick 			{
13922806Smckusick 			inequiv = NO;
14022806Smckusick 			if(np->vstg==STGEQUIV)
14122806Smckusick 				if( (ovarno = np->vardesc.varno) == i)
14222806Smckusick 					{
14322806Smckusick 					if(np->voffset + q->eqvoffset != 0)
14422806Smckusick 						dclerr("inconsistent equivalence", np);
14522806Smckusick 						doeqverr = 1;
14622806Smckusick 					}
14722806Smckusick 				else	{
14822806Smckusick 					offset = np->voffset;
14922806Smckusick 					inequiv = YES;
15022806Smckusick 					}
15122806Smckusick 
15222806Smckusick 			np->vstg = STGEQUIV;
15322806Smckusick 			np->vardesc.varno = i;
15422806Smckusick 			np->voffset = - q->eqvoffset;
15522806Smckusick 
15622806Smckusick 			if(inequiv)
15722806Smckusick 				eqveqv(i, ovarno, q->eqvoffset + offset);
15822806Smckusick 			}
15922806Smckusick 		}
16022806Smckusick 	}
16122806Smckusick 
16222806Smckusick if( !doeqverr )
16322806Smckusick   for(i = 0 ; i < nequiv ; ++i)
16422806Smckusick 	{
16522806Smckusick 	p = & eqvclass[i];
16622806Smckusick 	if(p->eqvbottom!=0 || p->eqvtop!=0)	/* a live chain */
16722806Smckusick 		{
16822806Smckusick 		for(q = p->equivs ; q; q = q->eqvnextp)
16922806Smckusick 			{
17022806Smckusick 			np = q->eqvitem.eqvname;
17122806Smckusick 			np->voffset -= p->eqvbottom;
17222806Smckusick 			if(np->voffset % typealign[np->vtype] != 0)
17322806Smckusick 				dclerr("bad alignment forced by equivalence", np);
17422806Smckusick 			}
17522806Smckusick 		p->eqvtop -= p->eqvbottom;
17622806Smckusick 		p->eqvbottom = 0;
17722806Smckusick  		}
17822806Smckusick 	freqchain(p);
17922806Smckusick 	}
18022806Smckusick }
18122806Smckusick 
18222806Smckusick 
18322806Smckusick 
18422806Smckusick 
18522806Smckusick 
18622806Smckusick /* put equivalence chain p at common block comno + comoffset */
18722806Smckusick 
eqvcommon(p,comno,comoffset)18822806Smckusick LOCAL eqvcommon(p, comno, comoffset)
18922806Smckusick struct Equivblock *p;
19022806Smckusick int comno;
19122806Smckusick ftnint comoffset;
19222806Smckusick {
19322806Smckusick int ovarno;
19422806Smckusick ftnint k, offq;
19522806Smckusick register Namep np;
19622806Smckusick register struct Eqvchain *q;
19722806Smckusick 
19822806Smckusick if(comoffset + p->eqvbottom < 0)
19922806Smckusick 	{
20022806Smckusick 	errstr("attempt to extend common %s backward",
20122806Smckusick 		nounder(XL, extsymtab[comno].extname) );
20222806Smckusick 	freqchain(p);
20322806Smckusick 	return;
20422806Smckusick 	}
20522806Smckusick 
20622806Smckusick if( (k = comoffset + p->eqvtop) > extsymtab[comno].extleng)
20722806Smckusick 	extsymtab[comno].extleng = k;
20822806Smckusick 
20922806Smckusick #ifdef SDB
21022806Smckusick if(sdbflag)
21122806Smckusick 	prstab( varstr(XL,extsymtab[comno].extname), N_BCOMM,0,0);
21222806Smckusick #endif
21322806Smckusick 
21422806Smckusick for(q = p->equivs ; q ; q = q->eqvnextp)
21522806Smckusick 	if(np = q->eqvitem.eqvname)
21622806Smckusick 		{
21722806Smckusick 		switch(np->vstg)
21822806Smckusick 			{
21922806Smckusick 			case STGUNKNOWN:
22022806Smckusick 			case STGBSS:
22122806Smckusick 				np->vstg = STGCOMMON;
22222806Smckusick 				np->vardesc.varno = comno;
22322806Smckusick 				np->voffset = comoffset - q->eqvoffset;
22422806Smckusick #ifdef SDB
22522806Smckusick 				if(sdbflag)
22622806Smckusick 					{
22722806Smckusick 					namestab(np);
22822806Smckusick 					}
22922806Smckusick #endif
23022806Smckusick 				break;
23122806Smckusick 
23222806Smckusick 			case STGEQUIV:
23322806Smckusick 				ovarno = np->vardesc.varno;
23422806Smckusick 				offq = comoffset - q->eqvoffset - np->voffset;
23522806Smckusick 				np->vstg = STGCOMMON;
23622806Smckusick 				np->vardesc.varno = comno;
23722806Smckusick 				np->voffset = comoffset + q->eqvoffset;
23822806Smckusick 				if(ovarno != (p - eqvclass))
23922806Smckusick 					eqvcommon(&eqvclass[ovarno], comno, offq);
24022806Smckusick #ifdef SDB
24122806Smckusick 				if(sdbflag)
24222806Smckusick 					{
24322806Smckusick 					namestab(np);
24422806Smckusick 					}
24522806Smckusick #endif
24622806Smckusick 				break;
24722806Smckusick 
24822806Smckusick 			case STGCOMMON:
24922806Smckusick 				if(comno != np->vardesc.varno ||
25022806Smckusick 				   comoffset != np->voffset+q->eqvoffset)
25122806Smckusick 					dclerr("inconsistent common usage", np);
25222806Smckusick 				break;
25322806Smckusick 
25422806Smckusick 
25522806Smckusick 			default:
25622806Smckusick 				badstg("eqvcommon", np->vstg);
25722806Smckusick 			}
25822806Smckusick 		}
25922806Smckusick 
26022806Smckusick #ifdef SDB
26122806Smckusick if(sdbflag)
26222806Smckusick 	prstab( varstr(XL,extsymtab[comno].extname), N_ECOMM,0,0);
26322806Smckusick #endif
26422806Smckusick 
26522806Smckusick freqchain(p);
26622806Smckusick p->eqvbottom = p->eqvtop = 0;
26722806Smckusick }
26822806Smckusick 
26922806Smckusick 
27022806Smckusick /* put all items on ovarno chain on front of nvarno chain
27122806Smckusick  * adjust offsets of ovarno elements and top and bottom of nvarno chain
27222806Smckusick  */
27322806Smckusick 
eqveqv(nvarno,ovarno,delta)27422806Smckusick LOCAL eqveqv(nvarno, ovarno, delta)
27522806Smckusick int ovarno, nvarno;
27622806Smckusick ftnint delta;
27722806Smckusick {
27822806Smckusick register struct Equivblock *p0, *p;
27922806Smckusick register Namep np;
28022806Smckusick struct Eqvchain *q, *q1;
28122806Smckusick 
28222806Smckusick p0 = eqvclass + nvarno;
28322806Smckusick p = eqvclass + ovarno;
28422806Smckusick p0->eqvbottom = lmin(p0->eqvbottom, p->eqvbottom - delta);
28522806Smckusick p0->eqvtop = lmax(p0->eqvtop, p->eqvtop - delta);
28622806Smckusick p->eqvbottom = p->eqvtop = 0;
28722806Smckusick 
28822806Smckusick for(q = p->equivs ; q ; q = q1)
28922806Smckusick 	{
29022806Smckusick 	q1 = q->eqvnextp;
29122806Smckusick 	if( (np = q->eqvitem.eqvname) && np->vardesc.varno==ovarno)
29222806Smckusick 		{
29322806Smckusick 		q->eqvnextp = p0->equivs;
29422806Smckusick 		p0->equivs = q;
29522806Smckusick 		q->eqvoffset -= delta;
29622806Smckusick 		np->vardesc.varno = nvarno;
29722806Smckusick 		np->voffset -= delta;
29822806Smckusick 		}
29922806Smckusick 	else	free( (charptr) q);
30022806Smckusick 	}
30122806Smckusick p->equivs = NULL;
30222806Smckusick }
30322806Smckusick 
30422806Smckusick 
30522806Smckusick 
30622806Smckusick 
freqchain(p)30722806Smckusick LOCAL freqchain(p)
30822806Smckusick register struct Equivblock *p;
30922806Smckusick {
31022806Smckusick register struct Eqvchain *q, *oq;
31122806Smckusick 
31222806Smckusick for(q = p->equivs ; q ; q = oq)
31322806Smckusick 	{
31422806Smckusick 	oq = q->eqvnextp;
31522806Smckusick 	free( (charptr) q);
31622806Smckusick 	}
31722806Smckusick p->equivs = NULL;
31822806Smckusick }
31922806Smckusick 
32022806Smckusick 
32122806Smckusick 
32222806Smckusick 
32322806Smckusick 
nsubs(p)32422806Smckusick LOCAL nsubs(p)
32522806Smckusick register struct Listblock *p;
32622806Smckusick {
32722806Smckusick register int n;
32822806Smckusick register chainp q;
32922806Smckusick 
33022806Smckusick n = 0;
33122806Smckusick if(p)
33222806Smckusick 	for(q = p->listp ; q ; q = q->nextp)
33322806Smckusick 		++n;
33422806Smckusick 
33522806Smckusick return(n);
33622806Smckusick }
337