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